Android как поживают активности


Содержание
Цукерберг рекомендует:  Javascript - Sublime Text 3

Как оставлять приложение всегда активным в Andro >

Поставил на смартфон+android несколько приложений месенджеров (skype, whatsup, telegram) и 2 разных будильника. Когда приложение активно (открыто на основном дисплее) — оно работает стабильно, если зайти в другое приложение оставив первое приложение на ‘втором фоне’ (не закрывая его), то второе приложение через пару часов нахождения в подобном «фоне» перестает работать (не принимает сообщений для мессенжеров и не звонит будильник).
Учитывая, что такое «засыпание» приложений начинается не сразу, а спустя пару часов, то это наводит на определенные мысли, что какой то процесс их принудительно завершает.
Как быть?

Функция отслеживания активности в Andro >Часть функционала Android 9.0 Pie появилась в виде отдельного приложения для того, чтобы его можно было обновлять через Google Play

Digital Wellbeing отслеживает активность пользователя и позволяет настраивать таймеры для приложений. Данная утилита показывает, сколько уведомлений приходит на устройство, как часто человек запускает то или иное приложение, сколько времени им пользуется. При желании, пользователь может настроить таймер для игр и программ: по истечении заданного времени, Digital Wellbeing уведомит человека о том, что пора перестать пользоваться конкретным приложением. Помимо вышеописанного, в утилите есть функция Wind Down. Она делает экран чёрно-белым незадолго до того, когда человек ложится спать.

Изначально предполагалось, что все возможности Digital Wellbeing будут частью настроек операционной системы. Однако ни в одной из бета-сборок Android 9.0 P не было отслеживания активности, из-за чего многие предположили, что Google сделает Digital Wellbeing эксклюзивом для грядущего поколения смартфонов Pixel. К счастью, «корпорация добра» попросту выпустила обещанный функционал в одном отдельном приложении (чтобы его можно было обновлять через Google Play).

Установить утилиту могут владельцы любых устройств на Android 9.0 P, но Digital Wellbeing заработает только на смартфонах линейки Pixel (по крайней мере, сейчас — в ходе тестирования).

Следим за своей девушкой с помощью Android

Содержание статьи

Сегодня мы проведем небольшое шпионское исследование и попробуем незаметно собрать данные о передвижении интересующего нас объекта — подруги, ребенка или, скажем, бабушки. Разумеется, с их письменно заверенного разрешения на сбор и обработку личной информации — как же иначе?

WARNING

Шпион, выйди вон

Общеизвестно, что любой современный смартфон (или планшет) оснащен модулем системы глобального позиционирования GPS, а то и православным ГЛОНАСС. Но даже если ты умудришься найти аппарат без него, карты Google (и не только) все равно смогут быстро обнаружить тебя на этом многострадальном голубом шарике. Для этого используется методика определения координат с помощью вышек сотовой связи, информацию о положении которых собирают абсолютно все игроки рынка геолокационных сервисов.

Ok, Google, вырубаем GPS и вынимаем симку, запускаем «Карты» и. внезапно снова видим свое положение. Оказывается, информации об окружающих точках Wi-Fi вполне достаточно для определения местоположения смартфона, пускай и не такого точного. В этой связи примечателен давний скандал с «картомобилем» Google, который тихо-мирно себе ездил и снимал улицы, попутно собирая названия всех точек доступа Wi-Fi. Тогда Google заявляла о некоем техническом сбое (!), но мы-то знаем.

Одним словом, смартфон почти всегда сможет определить свою ориентацию в родной Солнечной системе, чем мы и воспользуемся.

Операция «Спектр»

Театр начинается с вешалки, а приложение Android — с манифеста. Для доступа к GPS-приемнику необходимо добавить тег в секцию uses-permission:

Константа ACCESS_FINE_LOCATION задает высокий уровень точности для определения местоположения пользователя. Есть еще ACCESS_COARSE_LOCATION для более грубой геолокации, но нам она принципиально не интересна. К слову, приложение, которому было выдано полномочие fine, автоматически получает еще и полномочие coarse.

В Android для работы с геолокацией используется специальный интерфейс, предоставляемый системным объектом LocationManager:

Вторая геосоставляющая — LocationProvider, набор источников данных, каждый из которых отражает отдельную технологию поиска местоположения. Так, GPS_PROVIDER основывается на данных, полученных со спутников, NETWORK_PROVIDER шпионит за вышками сотовой связи и Wi-Fi.

Цукерберг рекомендует:  Php web - Что учить новичку в веб программировании

Наверное, в твоей голове уже созрел коварный план — периодически запрашивать координаты у GPS_PROVIDER и NETWORK_PROVIDER (например, с помощью фонового сервиса) и отправлять их в командный центр. Такое решение в лоб, конечно, имеет право на жизнь, но разве популярнейший журнал о безопасности стал бы о нем писать? Во-первых, это заметно — любое включение GPS отображается в статусной строке значком (рис. 1); во-вторых, это банально сажает батарею, что может заставить владельца задуматься и поискать прожорливое приложение; и, в-третьих, фоновый трафик прекрасно виден в системном журнале.

Рис. 1. GPS за работой

Специально для нас Google придумала отдельный провайдер — PASSIVE_PROVIDER, который получает информацию о местоположении только в том случае, если ее запрашивает другое приложение. Благодаря этому наш шпион будет получать обновления скрытым образом, без активации какого-либо источника LocationProvider. Иными словами, стоит пользователю запустить карту, клиент социальной сети, выйти в интернет, отправить сообщение и далее по списку, как наше приложение уже будет в курсе (рис. 2–3). Обратной стороной пассивности (и скрытности) является полное доверие к получаемым данным, мы никак не сможем проверить их достоверность.

Рис. 2. Первый запуск после загрузки устройства Рис. 3. Второй запуск после сеанса в Google Maps

Координаты «Скайфолл»

Для получения координат от источника данных существует метод getLastKnownLocation:

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

Как уже отмечалось, ни PASSIVE_PROVIDER, ни getLastKnownLocation не запрашивают у LocationProvider обновление местоположения. Если смартфон долго не обновлял текущую позицию, полученное значение может быть неактуальным или вовсе не существовать (например, сразу после загрузки).

Если ты снова подумал об использовании фонового сервиса для «дергания» PASSIVE_PROVIDER, спешу тебя огорчить: все гораздо проще. Наш выбор — широковещательный приемник (если не знаешь, что это, срочно загляни в сентябрьский «Хакер» или читай дальше).

Шаровая молния

Данные GPS, возвращаемые методом getLastKnownLocation или широковещательным приемником, не изменятся, пока хотя бы одна программа не запросит обновление местоположения. В итоге при первом запуске эмулятора getLastKnownLocation, скорее всего, вернет null, а приемник и вовсе откажется срабатывать.

Чтобы это исправить, можно воспользоваться следующим трюком:

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

Засылаем координаты в эмулятор

На секретной службе Ее Величества

Вкратце напомню: в качестве механизма передачи сообщений на уровне системы намерения (Intent) способны отправлять структурированные данные от процесса к процессу (например, информацию от GPS-модуля). Для отслеживания таких данных и реакции на них реализуются специальные объекты — широковещательные приемники. Основное их достоинство (для нас) — они срабатывают даже тогда, когда приложение находится в фоне, а некоторые (например, прием СМС) вообще не требуют запуска родительского приложения.

Каркас нашего приемника представлен ниже:

Метод onReceive будет срабатывать всякий раз при изменении координат устройства, но сначала приведенный приемник необходимо зарегистрировать в манифесте:

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Жизненный цикл Andro >
    Переводы, 7 апреля 2020 в 0:24

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

Чтобы обеспечить такой UX, вам следует знать, как управлять жизненными циклами компонентов, таких как активности, фрагменты, сервисы, приложение в целом и так далее. Во время работы компонент проходит через состояния, определяемые его жизненным циклом. Система уведомляет о таких переходах через методы обратного вызова (callbacks).

Обратите внимание: Диаграммы описывают поведение в Android P / Jetpack 1.0.

Диаграммы показывают сценарии поведения по умолчанию, если не указано иное.

Жизненный цикл одной активности

Сценарий 1: завершение и повторный запуск приложения

Источники

  • Нажатие кнопки «Back».
  • Вызов метода Activity.finish() .

Этот простейший сценарий показывает, что происходит, когда приложение с одной активностью завершается и снова запускается пользователем:

Сценарий 1: приложение завершено и перезапущено

Управление состоянием

  • onSaveInstanceState() не вызывается (активность завершается, поэтому не нужно сохранять её состояние);
  • onCreate() не принимает Bundle, так как предыдущая активность завершилась и не требует восстановления.

Сценарий 2: переход пользователя из приложения

Источники

  • Нажатие кнопки «Home».
  • Переключение на другое приложение (через кнопку «Overview», ответ на уведомление, приём входящего вызова и т. п.).

Сценарий 2: пользователь покидает приложение

В этом случае система остановит активность, но не будет сразу же завершать её.

Управление состоянием


Когда активность входит в остановленное состояние, система вызывает onSaveInstanceState() для сохранения состояния приложения на случай, если она завершит процесс впоследствии.

Nice, Санкт-Петербург, от 150 000 ₽

Предполагая, что процесс всё же не будет завершён, активность вместе со своим состоянием остаётся резидентной в памяти. Когда активность возвращается на передний план, её состояние доступно целиком и нет необходимости в повторной инициализации ранее созданных компонентов.

Сценарий 3: изменение конфигурации

Источники

  • Смена конфигурации, например поворот экрана.
  • Изменение размера окна в мультиоконном режиме.

Сценарий 3: поворот и другие изменения конфигурации

Управление состоянием

Изменения конфигурации вроде поворота и увеличения или уменьшения окна, должны позволять пользователям продолжать работу именно там, где они остановились:

  • предыдущая активность полностью разрушается, но её состояние сохраняется и передаётся новой;
  • в onCreate() и onRestoreInstanceState() передаётся один и тот же Bundle.

Сценарий 4: остановка приложения системой

Источники

  • Вход в мультиоконный режим (API 24+) и потеря фокуса.
  • Другое приложение, частично перекрывающее текущее (диалог покупки, запрос разрешения, сторонний диалог логина).
  • Выбор Intent, например «Поделиться».

Сценарий 4 — остановка приложения системой

Сценарий не относится к следующим случаям:

  • Диалоги в этом же приложении — показ AlertDialog или DialogFragment не приведёт к остановке активности.
  • Уведомления — пользователь, получающий уведомление или открывающий их панель, не остановит активность.

Примечание Показанные друг напротив друга группы событий отрабатываются параллельно. Поток выполнения может переключиться с одной группы событий на другую в любой момент времени, поэтому порядок вызовов методов из параллельных групп не определён. Однако последовательный порядок вызовов методов внутри группы гарантирован. Следующие сценарии не применяются к активностям и задачам с кастомным режимом запуска или заданным контекстом задачи (task affinity). За более подробной информацией обратитесь к документации на Android Developers.

Сценарий 1: навигация между активностями

Cценарий 1: завершение и повторный запуск приложения

В этом сценарии при старте новой активности первая останавливается (но не разрушается), что похоже на переход пользователя из приложения (по кнопке «Home»).

После нажатия на кнопку «Back» вторая активность разрушается и завершается.

Управление состоянием

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

Если система убьёт процесс для освобождения ресурсов, будет иметь место другой сценарий, в котором состояние потребуется восстановить.

Сценарий 2: активности в стеке переходов и изменения конфигурации

Сценарий 2: активности в стеке переходов и изменения конфигурации

Управление состоянием

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

Кроме того, система может завершить процесс почти в любой момент, так что следует быть готовым восстановить состояние в любой ситуации.

Завершение процесса

Когда Android нуждается в ресурсах, он завершает фоновые приложения.

Сценарий 3: завершение процесса

Управление состоянием

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

Узнать больше можно здесь.

Жизненный цикл фрагментов

В этой части обсудим поведение прикреплённых к активности фрагментов. Не смущайтесь сценария с добавлением фрагмента в стек переходов назад (подробнее о транзакциях фрагментов и стеке переходов здесь).

Сценарий 1: запуск активности с фрагментом и её завершение

Сценарий 1: запуск активности с фрагментом и её завершение

Гарантировано, что вызов onCreate() активности выполнится раньше соответствующих вызовов фрагментов. Однако противолежащие методы обратного вызова, такие как onStart() и onResume() , выполняются параллельно, и поэтому порядок их вызовов не определён. Например, система может выполнить метод onStart() активности перед методом onStart() фрагмента, но выполнить метод onResume() фрагмента перед методом onResume() активности.

Примечание Будьте осторожны при управлении потоками выполнения и избегайте состояния гонки.

Сценарий 2: поворот активности с фрагментом

Сценарий 2: поворот действия с фрагментом

Управление состоянием

Сохранение и восстановление фрагментов очень похоже на сохранение и восстановление активностей. Различие заключается в том, что у фрагментов нет метода onRestoreInstanceState() , но им доступен Bundle в методах onCreate() , onCreateView() и onActivityCreated() .

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

Сценарий 3: поворот активности с сохранённым фрагментом

Сценарий 3: поворот активности с сохранённым фрагментом

После поворота фрагмент не разрушается и не воссоздаётся, потому что после пересоздания активности используется тот же экземпляр фрагмента — при этом в onActivityCreated() всё ещё доступен объект состояния.

Не рекомендуется применять сохраняемые фрагменты, если они не используются для сохранения данных между изменениями конфигурации (в не UI-фрагменте). Класс ViewModel из библиотеки Architecture Components внутри реализован именно так, но он предоставляет более простой API.

ViewModels, полупрозрачные активности и режимы запуска

Модели представления (ViewModels)

Жизненный цикл модели представления достаточно простой — она имеет всего один метод обратного вызова, который называется onCleared() . Тем не менее, для модели представления есть различие между активностью и фрагментом:


Различие между активностью и фрагментом

Стоит обратить внимание, что инициализация случается всякий раз, когда вы получаете ViewModel , что обычно происходит в onCreate() .

Полупрозрачные активности

Из названия понятно, что у полупрозрачной активности полупрозрачный фон (как правило, совсем прозрачный). Таким образом, пользователь видит, что находится под ней.

Когда к теме активности применяется свойство android:windowIsTranslucent , диаграмма немного меняется: фоновая активность никогда не останавливается (только входит в состояние паузы), так что она может продолжать получать обновления UI:

Сравнение обычной и полупрозрачной активностей

Также при возвращении обратно к задаче, обе активности восстанавливаются и запускаются, и только полупрозрачная возобновляется:

Новая полупрозрачная активность: выход из приложения и повторное открытие

Режимы запуска

Рекомендованный способ работы с задачами и стеками переходов в своей основе прост — вы должны следовать поведению по умолчанию. За подробной информацией обратитесь к статье.

Если вам действительно нужен режим SINGLE_TOP , вот диаграмма:

Для сравнения посмотрите на следующей диаграмме режим singleTask (но, скорее всего, вам не нужно его использовать):

Если вы используете Navigation Architecture из Jetpack, то получите выгоду от поддержки Single Top и автоматического искусственного стека переходов.

Что такое Activity и его жизненный цикл в Android

Russian (Pусский) translation by Ellen Nelson (you can also view the original English article)

Из моей предыдущей статьи вы узнали, что Intents позволяют отправлять сообщения с одного компонента Android на другой. А очень важным компонентом является Activity.

Activities являются основной частью разработки приложений для Android. И невозможно понять Activity, не понимая их жизненных циклов. В этом материале вы узнаете всё о жизненном цикле Activity.

Жизненный цикл Activity

Activity — это отдельный экран в Android. Это как окно в приложении для рабочего стола, или фрейм в программе на Java. Activity позволяет вам разместить все ваши компоненты пользовательского интерфейса или виджеты на этом экране.

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

Методы жизненного цикла

Давайте поближе рассмотрим жизненный цикл Android Activity. Каждый раз, когда Activity меняет стадию, вызывается один из следующих методов жизненного цикла для класса Activity.

onCreate() : вызывается при первой инициализации Activity. Вам нужно выполнить этот метод для выполнения любой инициализации в вашей Activity.

onStart() : это вызывается, когда Activity готова и отображается пользователю в первый раз, так как Activity готовится стать интерактивной и выйти на передний план. После завершения вызова этого метода, будет вызван метод onResume() .

onResume() : когда Activity переходит в это состояние, оно начинает взаимодействовать с пользователем. Activity продолжает работать в этом состоянии, пока что-либо не уведёт фокус от приложения или Activity (например, входящий звонок). Если это произойдет, будет вызван метод onPause() .

onPause() : этот метод используется для приостановки действий, которые не должны происходить, пока Activity в стадии паузы. Вызов этого метода указывает на то, что пользователь покинул приложение. К примеру, входящий звонок может перевести, проигрыватель музыки в состояние паузы. Это должно заглушить или остановить воспроизводящуюся музыку. Когда пользователь возвращается в приложение, вызывается метод onResume() .

onStop() : этот метод вызывается, если Activity больше не видна в приложении. Такое может случится, если подгружена другая Activity и она занимает весь экран устройства. Когда вызывает этот метод, Activity сообщается перейти в состояние прекращения работы. В этом состоянии, система либо вызывает onRestart() для возврата взаимодействия с Activity, либо вызывает метод onDestroy() , чтобу убрать Activity.

onDestroy() : этот метод вызывается перед тем, как Activity будет завершена. Система вызывает этот метод, когда пользователь завершает Activity, или если система временно убирает процесс, содержащий Activity, для высвобождения места. С этом методом, обязательно освободите любые ресурсы, созданные вашей Activity, иначе ваше приложение будет иметь утечку памяти.

onRestart() : это вызывается, если Activity перезапускается, после того, как было остановлено.

Запуск Activity

Большинство пользовательских взаимодействий приводит к изменению действующей Activity. Поэтому приложение моно раз переключается между Activity за свой жизненный цикл.

Необходимо связывать Activity друг с другом, если требуется чтобы одна Activity запускала другую. Для запуска Activity используйте либо startActivity() , либо startActivityForResult() . В обоих случаях вы должны передать Intent.

Запуск Activity без ожидаемого результата

startActivity() используется, если недавно запущенная Activity не должна возвращать результат.

Следующий фрагмент кода показывает как начать другую Activity, используя этот метод:

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

Запуск Activity на результат

startActivityForResult() используется для запуска другой Activity и ожидает получение данных в эту свежезапущенную Activity. Другими словами, используйте это если хотите получить результат от целевой Activity в вызывающую Activity, т.е. если целевая Activity собирает некую пользовательскую информацию в модальном диалоговом окне.

Вы получите результат от Activity в методе onActivityResult(int requestCode, int resultCode, Intent data) . Результат будет возвращен в качестве Intent.

Пример запуска Activity

Вот пример, который показывает как работает запуск Activity

Во-первых создайте MainActivity с вашим методом onCreate() , файл макета и кодом запроса.

В методе onCreate() вы создадите новый экземпляр намерения (intent) чтобы запустить вторую Activity.

Когда будете готовы к запуску Activity, скажем в ответ на нажатие кнопки, вы вызовете startActivityForResult() , которая передаст свеже-созданное намерение и код запроса.

В вашей MainActivity , вам всё же нужно обработать результат событий Activity. Это выполняется путём реализации метода onActivityResult() . Вот так вы и получите результат от другой Activity.

Вот как это должно выглядеть:

Теперь создайте вашу SecondActivity . Это должно быть похоже на код ниже.

Прерывание Activity

Перед завершением Activity, будут вызваны соответствующие методы жизненного цикла.

Метод onPause() должен остановить все «слушания» и обновления интерфейса. Метод onStop() должен сохранять данные приложения. И наконец, метод onDestroy() высвободит любые ресурсы, выделенные для Activity.

Когда пользователь переключается обратно на приложение, которое было прервано системным событием, вызывается метод onResume() . На основе сохраненных данных, могут перерегистрироваться «слушатели» и переключиться обновления интерфейса.

Стадия экземпляра Activity

Activity нужен способ сохранить полезное состояние и пользовательские данные, которые она получила. Эти данные могут быть получены от пользователя или созданы, пока Activity не отображалась на экране.

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

Чтобы сохранить состояние Activity, можно переопределить метод onSaveInstanceState(). Этот метод передаёт объект Bundle , в качестве параметра. Пакет (bundle) может содержать строки, простые типы данных или объекты. В этом методе, просто добавьте любые данные о важном состоянии в пакет (bundle). Позже этот пакет вернется Activity, так что вы сможете восстановить состояние Activity.

Чтобы извлечь сохраненное состояние из пакета и восстановить его (состояние), примените метод onRestoreInstanceState() . Этот callback вызывается между методами жизненного цикла onStart() и onResume() .

Мы получше рассмотрим состояние экземпляра Activity в будущих статьях.

Заключение

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

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

Andro >

Есть ли собственный способ для Android, чтобы получить ссылку на текущую активность из службы?

У меня есть служба, работающая в фоновом режиме, и я хотел бы обновить текущую активность, когда происходит событие (в службе). Есть ли простой способ сделать это (например, тот, который я предложил выше)?

Есть ли собственный способ для Android, чтобы получить ссылку на текущую активность из службы?


Возможно, вам не принадлежит «текущая активность».

У меня есть служба, работающая в фоновом режиме, и я хотел бы обновить текущую активность, когда происходит событие (в службе). Есть ли простой способ сделать это (например, тот, который я предложил выше)?

  1. Отправить трансляцию Intent к деятельности – вот пример проекта, демонстрирующий этот шаблон
  2. Предложите ли вы действие PendingIntent (например, через createPendingResult() ), которое вызывает служба
  3. Регистрировать объект обратного вызова или слушателя с помощью службы через bindService() и вызвать вызов службы методом события в этом объекте обратного вызова / прослушивателя
  4. Отправляйте заказное вещательное Intent в действие с низкоприоритетным BroadcastReceiver качестве резервной копии (чтобы повысить Notification если активность не отображается на экране) – вот сообщение в блоге с более подробным описанием этого шаблона

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

Существует простой способ получить список запущенных задач из службы ActivityManager. Вы можете запросить максимальное количество задач, выполняемых на телефоне, и по умолчанию возвращается текущая активная задача.

После этого вы можете получить объект ComponentName, запросив topActivity из вашего списка.

Вам понадобится следующее разрешение на ваш манифест:

Использовать AccessibilityService

  • Вы можете обнаружить текущее активное окно с помощью AccessibilityService .
  • В onAccessibilityEvent проверьте TYPE_WINDOW_STATE_CHANGED события TYPE_WINDOW_STATE_CHANGED чтобы определить, когда изменяется текущее окно.
  • Проверьте, является ли это окно активным, вызывая PackageManager.getActivityInfo() .

Выгоды

  • Протестировано и работает в Android 2.2 (API 8) через Android 7.1 (API 25).
  • Не требует опроса.
  • Не требует разрешения GET_TASKS .

Недостатки

  • Каждый пользователь должен включить службу в настройках доступности Android.
  • Служба всегда работает.
  • Когда пользователь пытается включить AccessibilityService , они не могут нажать кнопку OK, если приложение разместило наложение на экране. Некоторые приложения, которые делают это, это Velis Auto Brightness и Lux. Это может сбить с толку, потому что пользователь может не знать, почему они не могут нажать кнопку или как ее обойти.
  • AccessibilityService не будет знать текущую активность до первого изменения активности.

пример

обслуживание

AndroidManifest.xml

Объедините это в свой манифест:

Сервисная информация

Поместите это в res/xml/accessibilityservice.xml :

Включение службы

Каждому пользователю приложения необходимо будет явно включить AccessibilityService для его использования. См. Этот ответ StackOverflow для того, как это сделать.

Обратите внимание, что пользователь не сможет нажать кнопку OK при попытке включить службу доступности, если приложение разместило наложение на экране, например, Velis Auto Brightness или Lux.

Использовать ActivityManager

Если вы хотите узнать приложение, содержащее текущую активность, вы можете сделать это с помощью ActivityManager . Техника, которую вы можете использовать, зависит от версии Android:

  • Pre-Lollipop: ActivityManager.getRunningTasks ( пример )
  • Lollipop: ActivityManager.getRunningAppProcesses ( пример )

Выгоды

  • Должен работать во всех версиях Android.

Недостатки

  • Не работает в Android M (на основе тестирования с использованием эмулятора предварительного выпуска)
  • Документация для этих API говорит, что они предназначены только для пользовательских интерфейсов отладки и управления.
  • Если вам нужны обновления в реальном времени, вам нужно использовать опрос.
  • Опирается на скрытый API: ActivityManager.RunningAppProcessInfo.processState
  • Эта реализация не отображает активность переключателя приложений.

Пример (на основе кода KNaito )

манифест

Добавьте разрешение GET_TASKS в AndroidManifest.xml :

Я использую это для своих тестов. Это API> 19, и только для действий вашего приложения.

Я не мог найти решение, в котором наша команда была бы счастлива, поэтому мы катались самостоятельно. Мы используем ActivityLifecycleCallbacks для отслеживания текущей активности, а затем выставляем ее через службу:

Затем настройте контейнер DI для возврата экземпляра MyApplication для ContextProvider , например

(Обратите внимание, что реализация getCurrent() не getCurrent() из приведенного выше кода. Это просто статическая переменная, заданная из конструктора приложения)


Это можно сделать:

Внесите свой собственный класс приложения, зарегистрируйтесь для ActivityLifecycleCallbacks – таким образом вы можете увидеть, что происходит с нашим приложением. При каждом возобновлении обратный вызов назначает текущую видимую активность на экране и на паузе удаляет присвоение. Он использует метод registerActivityLifecycleCallbacks() который был добавлен в API 14.

В своем сервисе вызовите getApplication() и getApplication() его к имени своего приложения (приложение в этом случае). Чем вы можете позвонить app.getActiveActivity() – это даст вам текущую видимую активность (или null, если активность не видна). Вы можете получить имя Activity, вызвав activeActivity.getClass().getSimpleName()

Вот мой ответ, который отлично работает …

Вы должны иметь возможность получать текущую активность таким образом … Если вы структурируете свое приложение несколькими Действиями со многими фрагментами, и вы хотите отслеживать, какова ваша текущая деятельность, это займет много работы. Мой senario был у меня есть одно действие с несколькими фрагментами. Поэтому я могу отслеживать текущую активность через Application Object, которая может хранить все текущее состояние глобальных переменных.

Вот путь. Когда вы начинаете свою деятельность, вы сохраняете это Activity by Application.setCurrentActivity (getIntent ()); Это приложение сохранит его. В вашем классе обслуживания вы можете просто сделать это как Intent currentIntent = Application.getCurrentActivity (); . GetApplication () startActivity (currentIntent);

Используйте этот код для API 21 или выше. Это работает и дает лучший результат по сравнению с другими ответами, он отлично распознает процесс переднего плана.

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

Activity

Activity и жизненный цикл приложения

Ключевым компонентом для создания визуального интерфейса в приложении Android является activity (активность). Нередко activity ассоциируется с отдельным экраном или окном приложения, а переключение между окнами будет происходить как перемещение от одной activity к другой. Приложение может иметь одну или несколько activity. Например, в прошлой теме работа приложения начиналась с класса MainActivity:

Все объекты activity представляют собой объекты класса android.app.Activity , которая содержит базовую функциональность для всех activity. В приложении из прошлой темы мы напрямую с этим классом не работали, а MainActivity наследовалась от класса AppCompatActivity . Однако сам класс AppCompatActivity, хоть и не напрямую, наследуется от базового класса Activity.

Жизненный цикл приложения

Все приложения Android имеют строго определенный системой жизненный цикл. При запуске пользователем приложения система дает этому приложению высокий приоритет. Каждое приложение запускается в виде отдельного процесса, что позволяет системе давать одним процессам более высокой приоритет, в отличие от других. Благодаря этому, например, при работе с одними приложениями не блокировать входящие звонки. После прекращения работы с приложением, система освобождает все связанные ресурсы и переводит приложение в разряд низкоприоритетного и закрывает его.

Все объекты activity, которые есть в приложении, управляются системой в виде стека activity, который называется back stack . При запуске новой activity она помещается поверх стека и выводится на экран устройства, пока не появится новая activity. Когда текущая activity заканчивает свою работу (например, пользователь уходит из приложения), то она удаляется из стека, и возобновляет работу та activity, которая ранее была второй в стеке.

После запуска activity проходит через ряд событий, которые обрабатываются системой и для обработки которых существует ряд обратных вызовов:

Схематично взаимосвязь между всеми этими обратными вызовами можно представить следующим образом

onCreate()

onCreate — первый метод, с которого начинается выполнение activity. В этом методе activity переходит в состояние Created. Этот метод обязательно должен быть определен в классе activity. В нем производится первоначальная настройка activity. В частности, создаются объекты визуального интерфейса. Этот метод получает объект Bundle , который содержит прежнее состояние activity, если оно было сохранено. Если activity заново создается, то данный объект имеет значение null. Если же activity уже ранее была создана, но находилась в приостановленном состоянии, то bundle содержит связанную с activity информацию.

onStart

В методе onStart() осуществляется подготовка к выводу activity на экран устройства. Как правило, этот метод не требует переопределения, а всю работу производит встроенный код. После завершения работы метода activity отображается на экране, вызывается метод onResume , а activity переходит в состояние Resumed.

onRestoreInstanceState

После завершения метода onStart() вызывается метод onRestoreInstanceState , который призван восстанавливать сохраненное состояние из объекта Bundle, который передается в качестве параметра. Но следует учитывать, что этот метод вызывается только тогда, когда Bundle не равен null и содержит ранее сохраненное состояние. Так, при первом запуске приложения этот объект Bundle будет иметь значение null, поэтому и метод onRestoreInstanceState не будет вызываться.

onResume

А при вызове метода onResume activity переходит в состояние Resumed, а пользователь может с ней взаимодействовать. И собственно activity остается в этом состоянии, пока она не потеряет фокус, например, вследствии переключения на другую activity или просто из-за выключения экрана устройства.

onPause

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

Но надо учитывать, что на работу данного метода отводится очень мало времени, поэтому не стоит здесь сохранять какие-то данные, особенно если при этом требуется обращение к сети, например, отправка данных по интернету, или обращение к базе данных.

После выполнения этого метода activity становится невидимой, не отображается на экране, но она все еще активна. И если пользователь решит вернуться к этой activity, то система вызовет снова метод onResume , и activity снова появится на экране.

Другой вариант работы может возникнуть, если вдруг система видит, что для работы активных приложений необходимо больше памяти. И система может сама завершить полностью работу activity, которая невидима и находится в фоне. Либо пользователь может нажать на кнопку Back (Назад). В этом случае у activity вызывается метод onStop .

onSaveInstanceState

Метод onSaveInstanceState вызывается после метода onPause() , но до вызова onStop() . В onSaveInstanceState производится сохранение состояния приложения в передаваемый в качестве параметра объект Bundle.

onStop

В этом методе activity переходит в состояние Stopped. В методе onStop следует особождать используемые ресурсы, которые не нужны пользователю, когда он не взаимодействует с activity. Здесь также можно сохранять данные, например, в базу данных.

При этом во время состояния Stopped activity остается в памяти устройства, сохраняется состояние всех элементов интерфейса. К примеру, если в текстовое поле EditText был введен какой-то текст, то после возобновления работы activity и перехода ее в состояние Resumed мы вновь увидим в текстовом поле ранее введенный текст.

Если после вызова метода onStop пользователь решит вернуться к прежней activity, тогда система вызовет метод onRestart . Если же activity вовсе завершила свою работу, например, из-за закрытия приложения, то вызывается метод onDestroy() .

onDestroy

Ну и завершается работа активности вызовом метода onDestroy , который возникает либо, если система решит убить activity, либо при вызове метода finish() .

Также следует отметить, что при изменении ориентации экрана система завершает activity и затем создает ее заново, вызывая метод onCreate .

В целом переход между состояниями activity можно выразить следующей схемой:

Расмотрим несколько ситуаций. Если мы работаем с Activity и затем переключаемся на другое приложение, либо нажимаем на кнопку Home, то у Activity вызывается следующая цепочка методов: onPause -> onStop . Activity оказывается в состоянии Stopped. Если пользователь решит вернуться к Activity, то вызывается следующая цепочка методов: onRestart -> onStart -> onResume .

Другая ситуация, если пользователь нажимает на кнопку Back (Назад), то вызывается следующая цепочка onPause -> onStop -> onDestroy . В результате Activity уничтожается. Если мы вдруг захотим вернуться к Activity через диспетчер задач или заново открыв приложение, то activity будет заново пересоздаваться через методы onCreate -> onStart -> onResume

Управление жизненным циклом

Мы можем управлять этими событиями жизненного цикла, переопределив соответствующие методы. Для этого возьмем из прошлой главы класс MainActivity и изменим его следующим образом:

Для логгирования событий здесь используется класс android.util.Log .

В данном случае обрабатываются все ключевые методы жизненного цикла. Вся обработка сведена к вызову метода Log.d() , в который передается TAG — случайное строковое значение и строка, которая выводится в консоли logcat внизу Andro >View -> Tool Windows -> Android Monitor .

И при запуске приложения мы сможем увидеть в окне logcat отладочную информацию, которая определяется в методах жизненного цикла activity:

Network Connections — мониторинг сетевой активности Andro >

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

Это удобный бесплатный инструмент, предназначенный для сетевых администраторов и просто продвинутых пользователей, который поможет им контролировать входящий и исходящий трафик своего телефона под управлением Android. Приложение дает полное представление о всех интернет-соединениях, использующих их службах и приложениях, IP-адресах.

Network Connections имеет простой и понятный интерфейс. Все данные разделены на несколько вкладок: Current Connections, Connections Log, App Network Log и Settings. Первая вкладка позволяет увидеть список IP адресов, с которыми установлено соединение. Здесь также отображается объем отправленных и полученных через каждое подключение данных, что может пригодиться для отслеживания подозрительной сетевой деятельности.

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

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

Полный список

— Activity LifeCycle – поведение Activity при создании, вызове, закрытии

Теория

При работе приложения, мы создаем новые Activity и закрываем старые, сворачиваем приложение, снова открываем и т.д. Activity умеет обрабатывать все эти движения. Это необходимо, например, для освобождения ресурсов или сохранения данных. В хелпе достаточно подробно это описано.

Созданное при работе приложения Activity может быть в одном из трех состояний:

Resumed — Activity видно на экране, оно находится в фокусе, пользователь может с ним взаимодействовать. Это состояние также иногда называют Running.
Paused — Activity не в фокусе, пользователь не может с ним взаимодействовать, но его видно (оно перекрыто другим Activity, которое занимает не весь экран или полупрозрачно).
Stopped — Activity не видно (полностью перекрывается другим Activity), соответственно оно не в фокусе и пользователь не может с ним взаимодействовать.

Когда Activity переходит из одного состояния в другое, система вызывает различные его методы, которые мы можем заполнять своим кодом. Схематично это можно изобразить так:

Для упрощения понимания я дал краткое описание состояний в скобках под названиями. А крестом обозначил отсутствие Activity.

Итак, мы имеем следующие методы Activity, которые вызывает система:

onCreate() – вызывается при первом создании Activity
onStart() – вызывается перед тем, как Activity будет видно пользователю
onResume() – вызывается перед тем как будет доступно для активности пользователя (взаимодействие)

onPause() – вызывается перед тем, как будет показано другое Activity
onStop() – вызывается когда Activity становится не видно пользователю
onDestroy() – вызывается перед тем, как Activity будет уничтожено

Т.е. эти методы НЕ вызывают смену состояния. Наоборот, смена состояния Activity является триггером, который вызывает эти методы. Тем самым нас уведомляют о смене, и мы можем реагировать соответственно. Посмотрим на практике, когда и в каком порядке вызываются эти методы.

Практика

В этом уроке нам надо будет эмулировать событие смены ориентации экрана. Но эмулятор с Android 2.3 делает это криво, поэтому в проекте будем использовать версию 2.2. Для этого надо создать новое AVD по версии 2.2

Создадим проект (обратите внимание, используем Android 2.2.):

Project name: P0231_OneActivityState
Build Target: Android 2.2
Application name: OneActivityState
Package name: ru.startandroid.develop.p0231oneactivitystate
Create Activity: MainActivity

Layout не меняем, нам он сейчас не важен. Открываем MainActivity.java, там как обычно код по умолчанию:

Мы видим, что реализован уже знакомый нам по схеме метод onCreate. Повторюсь, важно понимать, что этот метод НЕ создает Activity. Создание – это дело системы. Т.е. система сама создает Activity, а нам дает возможность немного поучаствовать и выполнить свой код в методе onCreate(). Мы этой возможностью пользуемся и говорим системе, что Activity должна отобразить экран из R.layout.main.

Добавим все остальные методы из схемы, и в каждый добавим запись в лог.

В каментах подсказали важное замечание! При реализации этих методов обязательно вызывайте соответствующие методы супер-класса и обязательно перед вашим кодом. См. код выше. Каждый метод содержит вызов метода супер-класса и свой код расположен после этих вызовов.

Теперь, когда методы будут вызываться, мы будем видеть это в логах. Настроим фильтр на тег «States», чтобы не искать свои сообщения в общей куче логов. Как это делается мы проходили в уроке 12

Все сохраним и запустим приложение. После того, как запустилось, смотрим лог:

MainActivity: onCreate()
MainActivity: onStart()
MainActivity: onResume()

Activity создалось, прошло два состояния (Stopped, Paused) и теперь находится в третьем состоянии — Resumed. Т.е. оно создалось (onCreate), отобразилось (onStart) и получило возможность взаимодействовать с пользователем (onResume).

Теперь нажмем кнопку Back на эмуляторе. Activity закрылось. Смотрим лог:

MainActivity: onPause()
MainActivity: onStop()
MainActivity: onDestroy()

Activity проделывает путь, обратный созданию. Сначала теряет фокус (onPause), затем исчезает с экрана (onStop), затем полностью уничтожается (onDestroy).

Смена ориентации экрана

Посмотрим, как ведет себя Activity, когда происходит смена ориентации экрана. Запустите снова приложение (либо найдите его в списке приложений в системе на эмуляторе, либо снова нажмите CTRL+F11 в Eclipse ). В логах снова отобразились три метода, вызванные при создании. Теперь в эмуляторе нажмите CTRL+F12, ориентация сменилась. Кажется, что ничего особенного не произошло, но смотрим логи и видим:

MainActivity: onPause()
MainActivity: onStop()
MainActivity: onDestroy()
MainActivity: onCreate()
MainActivity: onStart()
MainActivity: onResume()

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

Также есть еще метод onRestart. Он вызывается перед методом onStart, если Activity не создается с нуля, а восстанавливается из состояния Stoped. Его мы рассмотрим в следующем уроке.

Обычно в учебниках эта тема дается по-другому. Но мне это шаблонное объяснение кажется недостаточно понятным, поэтому я написал свое. Как всегда, надеюсь, что у меня получилось раскрыть тему )

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

На следующем уроке:

— изучаем смену состояния на примере двух Activity

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

ON LINE КЛУБ
РАДИОЛЮБИТЕЛЕЙ г.НОВОУКРАИНКА

Andro > Автор: stast от 8-11-2020, 07:15

Что такое активности?
Их жизненный цикл. Мы вместе заглянем поглубже на примере простого приложения «Секундомер».
Что происходит при создании и уничтожении активности?
Какие еще методы используются в жизненном цикле, и зачем?

Информация о фильме:
Название: Android: как поживают активности?
Год: 2020
Жанр: обучающее видео

Страна: Россия
Продолжительность: 01:52:08
Язык: Русский

Файл:
Качество: WEBRip
Формат: mpg
Битрейт: 1978 Kbps
Видео: mpg, 1280х720 , 25.00 fps(r)
Аудио: mp3, 48000 Hz, stereo
Размер:1,80 Гб

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих