Перейти к содержимому

Choose activity как убрать андроид

  • автор:

Решение проблем при разработке под Android

Unity не удаётся установить ваше приложение на ваше устройство

  1. Убедитесь, что ваш компьютер видит ваше устройство и может взаимодействовать с ним. Для деталей см. Публикация сборок.
  2. Проверьте консоль Unity на наличие сообщений об ошибках. Это часто помогает в определении проблемы.

Если у вас появляется ошибка “Unable to install APK, protocol failure” во время сборки, то это значит, что ваше устройство подключено через USB-порт с низким питанием (возможно порт на клавиатуре или ещё на какой-нибудь периферии). Если такое случается, то попробуйте подсоединить устройство в USB порт на самом компьютере.

Ваше приложение падает сразу после запуска.

  1. Убедитесь, что вы не пытаетесь использовать NativeActivity с устройствами, которые это не поддерживают.
  2. Попробуйте убрать все нативные плагины, что у вас есть.
  3. Попробуйте отключить stripping.
  4. Используйте adb logcat чтобы получить отчёт о крахе с вашего устройства.

Building DEX Failed

Это ошибка, которая выдаёт сообщение, вроде следующего:-

Building DEX Failed! G:\Unity\JavaPluginSample\Temp/StagingArea> java -Xmx1024M -Djava.ext.dirs="G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/" -jar "G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/dx.jar" --dex --verbose --output=bin/classes.dex bin/classes.jar plugins Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine. 

Обычно это вызвано неверной версией Java на вашем компьютере. Обновление Java до последней версии обычно решает проблему.

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

Убедитесь, что Settings->Developer Options->Don’t keep activities не включено на вашем телефоне. Проигрыватель видео — это отдельное приложение и поэтому обычное игровое приложение будет закрыто, если проигрыватель видео включён.

Моя игра закрывается, когда я жму кнопку сна

Измените тег activity в файле AndroidManifest.xml так , чтобы он содержал тег android:configChanges , сделайте это таким образом, как описано здесь.

Пример тега activity может выглядеть, например, вот так:-

Файл манифеста AndroidManifest.xml

Файл манифеста AndroidManifest.xml предоставляет основную информацию о программе системе. Каждое приложение должно иметь свой файл AndroidManifest.xml. Редактировать файл манифеста можно вручную, изменяя XML-код или через визуальный редактор Manifest Editor (Редактор файла манифеста), который позволяет осуществлять визуальное и текстовое редактирование файла манифеста приложения.

Назначение файла

  • объявляет имя Java-пакета приложения, который служит уникальным идентификатором;
  • описывает компоненты приложения — деятельности, службы, приемники широковещательных намерений и контент-провайдеры, что позволяет вызывать классы, которые реализуют каждый из компонентов, и объявляет их намерения;
  • содержит список необходимых разрешений для обращения к защищенным частям API и взаимодействия с другими приложениями;
  • объявляет разрешения, которые сторонние приложения обязаны иметь для взаимодействия с компонентами данного приложения;
  • объявляет минимальный уровень API Android, необходимый для работы приложения;
  • перечисляет связанные библиотеки;

Общая структура манифеста

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

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

Описание

Элемент является корневым элементом манифеста.

Атрибуты

xmlns:android определяет пространство имён Android. Оно всегда одно и то же package определяет уникальное имя пакета приложения, которое вы задали при создании проекта. Android Marketplace проверяет уникальность при приеме приложения, поэтому рекомендуется использовать свое имя для избежания конфликтов с другими разработчиками. Например, я использую имя своего сайта в обратном порядке: ru.alexanderklimov.appname. Сейчас в студии данный атрибут перекочевал в build.gradle в виде namespace в секции android. Из манифеста атрибут убрали. android:versionCode указывает на внутренний номер версии, используемый для сравнения версий программы. «versionCode» должен быть целым, и Android Market использует это для определения, предоставили ли вы новую версию, передавая триггеру обновления на устройствах, на которых установлено ваше приложение. Как правило. начинается с 1 и увеличивается на единицу, если вы выпускаете новую версию приложения. Сейчас в студии данный атрибут перекочевал в build.gradle android:versionName указывает номер пользовательской версии. Можно использовать строку или строковый ресурс. Этот номер видит пользователь. Сейчас в студии данный атрибут перекочевал в build.gradle

Читайте совет Получить номер версии программы

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

android:name название разрешения android:label имя разрешения, отображаемое пользователю android:description описание разрешения android:icon значок разрешения android:permissionGroup определяет принадлежность к группе разрешений android:protectionLevel уровень защиты

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

android:name имеет единственный атрибут с именем разрешения android:name. Это может быть разрешение, определенное в элементе данного приложения, разрешение, определенное в другом приложении или одно из стандартных системных разрешений, например: android:name=»android.permission.CAMERA» или android:name=»»android.permission.READ_CONTACTS»

Наиболее распространенные разрешения

  • INTERNET — доступ к интернету
  • READ_CONTACTS — чтение (но не запись) данных из адресной книги пользователя
  • WRITE_CONTACTS — запись (но не чтение) данных из адресной книги пользователя
  • RECEIVE_SMS — обработка входящих SMS
  • ACCESS_COARSE_LOCATION — использование приблизительного определения местонахождения при помощи вышек сотовой связи или точек доступа Wi-Fi
  • ACCESS_FINE_LOCATION — точное определение местонахождения при помощи GPS

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

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

Элемент объявляет объект instrumentation, который дает возможность контролировать взаимодействие приложения с системой. Обычно используется при отладке и тестировании приложения и удаляется из release-версии приложения.

Элемент позволяет объявлять совместимость приложения с указанной версией (или более новыми версиями API) платформы Android. Уровень API, объявленный приложением, сравнивается с уровнем API системы мобильного устройства, на который инсталлируется данное приложение.

Атрибуты

android:minSdkVersion определяет минимальный уровень API, требуемый для работы приложения. Система Android будет препятствовать тому, чтобы пользователь установил приложение, если уровень API системы будет ниже, чем значение, определенное в этом атрибуте. Вы должны всегда объявлять этот атрибут, например: android:minSdkVersion=»11″. Вы можете ради интереса установить значение 7, а потом 11 и сравнить внешний вид приложения. Например, у младшей версии не будет отображаться ActionBar. android:maxSDKVersion позволяет определить самую позднюю версию, которую готова поддерживать ваша программа. Ваше приложение будет невидимым в Google Play для устройств с более свежей версией. Рекомендуется устанавливать в том случае, когда вы точно уверены, что приложение не будет корректно работать на новой платформе. targetSDKVersion позволяет указать платформу, для которой вы разрабатывали и тестировали приложение. Устанавливая значение для этого атрибута, вы сообщаете системе, что для поддержки этой конкретной версии не требуется никаких изменений.

Элемент указывает требуемую для приложения аппаратную и программную конфигурацию мобильного устройства. Например, приложение могло бы определить требования обязательного наличия на устройстве физической клавиатуры или USB-nopTa. Спецификация используется, чтобы избежать установки приложения на устройствах, которые не поддерживают требуемую конфигурацию. Если приложение может работать с различными конфигурациями устройства, необходимо включить в манифест отдельные элементы для каждой конфигурации. Вы можете задать любую комбинацию, содержащие следующие устройства

  • reqFiveWayNav — используйте значение true, если приложению требуется устройство ввода, поддерживающее навигацию вверх, вниз, влево, вправо, а также нажатие выделенного элемента. К таким устройствам относятся трекболы и D-pad. В принципе устарело
  • reqHardKeyboard — используйте значение true, если приложению нужна аппаратная клавиатура.
  • reqKeyboardType — позволяет задать тип клавиатуры: nokeys, qwerty, twelvekey, undefined
  • reqNavigation — укажите одно из значений: nonav, dpad, trackball, wheel или undefined, если требуется устройство для навигации
  • reqTouchScreen — если требуется сенсорный экран, то используйте нужное значение из возможных вариантов: notouch, stylus, finger, undefined. Сейчас практически все устройства содержат сенсорный экран, поэтому тоже устарело

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

Элемент объявляет определенную функциональность, требующуюся для работы приложения. Таким образом, приложение не будет установлено на устройствах, которые не имеют требуемую функциональность. Например, приложение могло бы определить, что оно требует камеру с автофокусом. Если устройство не имеет встроенную камеру с автофокусом, приложения не будет инсталлировано.

android.hardware.camera требуется аппаратная камера android.hardware.camera.autofocus требуется камера с автоматической фокусировкой

Список можно увидеть здесь.

Можно переопределить требование по умолчанию, добавив атрибут required со значением false. Например, если вашей программе не требуется, чтобы камера поддерживала автофокус, то используйте вариант:

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

smallScreen как правило экраны QVGA normalScreen стандартные экраны HVGA и WQVGA largeScreen большие экраны xlargeScreen очень большие экраны, которые превосходят размеры планшетов anyDensity установите значение true, если ваше приложение способно масштабироваться для отображения на экране с любым разрешением.

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

Начиная с API 13 (Android 3), у тега появились новые атрибуты:

  • requiresSmallestWidthDp — указываем минимальную поддерживаемую ширину экрана (наименьшая сторона устройства) в аппаратно-независимых пикселях. С его помощью можно отфильтровать устройства при размещении приложения в Google Play
  • compatibleWidthLimitDp — задаёт верхнюю границу масштабирования для вашего приложения. Если экран устройства выходит за указанную границу, система включит режим совместимости.
  • largestWidthLimitDp — задаёт абсолютную верхнюю границу, за пределами которой ваше приложение точно не может быть смаштабировано. В этом случае приложение запускается в режиме совместимости, которую нельзя отключить. Следует избегать подобных ситуаций и разрабатывать макеты для любых экранов.

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

Элемент объявляет активность. Если приложение содержит несколько активностей, не забывайте объявлять их в манифесте, создавая для каждой из них свой элемент . Если активность не объявлена в манифесте, она не будет видна системе и не будет запущена при выполнении приложения или будет выводиться сообщение об ошибке.

Для этого класса зарегистрирован фильтр вызовов, определяющий, что это действие запущено в приложении (действие android:name=«android.intent.action.MAIN»). Определение категории (категория android:name=«android.intent.category.LAUNCHER» ) определяет, что это приложение добавлено в директорию приложений на Android-устройстве. Значения @ направляют файлы ресурсов, которые содержат актуальные значения. Это упрощает работу с разными ресурсами, такими как строки, цвета, значки.

Атрибуты

android:name имя класса. Имя должно включать полное обозначение пакета, но т. к. имя пакета уже определено в корневом элементе , имя класса, реализующего деятельность, можно записывать в сокращенном виде, опуская имя пакета android:label текстовая метка, отображаемая пользователю android:launcMode управление стеком. Подробнее android:parentActivityName В приложениях с API 16 и выше используется эта строка. Она сообщает, какая активность является родительской. Для старых устройств используйте метаданные

android:exported Позволяет или запрещает запускать активность другим приложениям. Если атрибута нет, то по умолчанию равно false и другие приложения не могут запускать вашу активность. Но если у активности есть интент-фильтры, то по умолчанию это значение будет уже равно true. Это может запутать новичков. Поэтому, если вы хотите запретить запуск через сторонние приложения, то явно указывайте нужное значение.

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

Изменение конфигурации во время выполнения программы

При изменении языка, региона или аппаратной конфигурации Android прерывает работу всех приложений и затем запускает их повторно, перезагружая значения из ресурсов. Подобное поведение не всегда уместно и желательно. Например, некоторые изменения конфигурации (ориентация экрана в пространстве, доступность клавиатуры) могут произойти только лишь из-за того, что пользователь повернул устройство или выдвинул клавиатуру. Вы можете настраивать, каким образом ваше приложение будет реагировать на подобные изменения, обнаруживая их и выполняя собственные действия. Чтобы заставить Активность отслеживать изменения конфигурации при выполнении программы, добавьте в ее узел в манифесте атрибут android:configChanges, указав, какие именно события хотите обрабатывать.

Перечислим некоторые значения, с помощью которых можно описать изменения конфигурации:

  • оrientation — положение экрана изменено с портретного на альбомное (или наоборот);
  • keyboardHidden — клавиатура (или D-pad и другое устройство) выдвинута или спрятана;
  • fontScale — пользователь изменил предпочтительный размер шрифта;
  • locale — пользователь выбрал новые языковые настройки;
  • keyboard — изменился тип клавиатуры; например, телефон может иметь 12-клавишную панель, при повороте которой появляется полноценная клавиатура. Или была подключена внешняя клавиатура.
  • touchscreen или navigation — изменился тип клавиатуры или способ навигации. Как правило, такие события не встречаются.
  • mcc или mnc — обнаружена новая SIM-карта, при этом изменились страна и код сотовой сети соответственно.
  • uiMode — изменился режим пользовательского интерфейса, например, при переключении между автомобильным, дневным и ночным режимами.
  • screenLayout — изменились характеристики экрана, например, при активации другого дисплея.
  • screenSize — изменлись размеры экрана, например, при смене ориентации. Появилось в Android 3 (API 12)
  • smallestScreenSize — изменился физический размер экрана, например, при подключении внешнего дисплея. Появилось в Android 3 (API 12)

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

Наличие атрибута android:configChanges отменяет перезапуск приложения при заданных изменениях конфигурации. Вместо этого внутри активности срабатывает метод onConfigurationChanged(). Переопределите его, чтобы появилась возможность обрабатывать изменения в конфигурации. Используйте переданный объект Configuration, чтобы получить новые значения. Не забудьте вызвать одноименный метод из родительского класса и перезагрузить измененные значения со всех ресурсов, которые используются внутри активности.

 @Override public void onConfigurationChanged(Configuration _newConfig) < super.onConfigurationChanged(_newConfig); [ . Обновите пользовательский интерфейс, используя данные из ресурсов . ] if (_newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) < [ . Реакция на измененную ориентацию экрана . ] >if (_newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO) < [ . Реакция на выдвигание/задвигание клавиатуры . ] >> 

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

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

Каждый тег поддерживает вложенные узлы . Элемент определяет типы намерений, на которые могут ответить деятельность, сервис или приемник намерений. Фильтр намерений объявляет возможности его родительского компонента — что могут сделать деятельность или служба и какие типы рассылок получатель может обработать. Фильтр намерений предоставляет для компонентов-клиентов возможность получения намерений объявляемого типа, отфильтровывая те, которые не значимы для компонента, и содержит дочерние элементы , , .

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

Элемент определяет категорию компонента, которую должно обработать намерение. Это строковые константы, определенные в классе intent, например:

Элемент добавляет спецификацию данных к фильтру намерений. Спецификация может быть только типом данных (атрибут mimeType), URI или ТИПОМ данных вместе с URI. Значение URI определяется отдельными атрибутами для каждой из его частей, т. е. URI делитСЯ на части: android:scheme, android:host, android:port, android:path или android:pathPrefix, android:pathPattern.

Элемент определяет пару «имя-значение» для элемента дополнительных произвольных данных, которыми можно снабдить родительский компонент. Составляющий элемент может содержать любое число элементов .

Элемент — это псевдоним для Activity, определенной в атрибуте targetActivity. Целевая деятельность должна быть в том же самом приложении, что и псевдоним, и должна быть объявлена перед псевдонимом деятельности в манифесте. Псевдоним представляет целевую деятельность как независимый объект. У псевдонима может быть свой собственный набор фильтров намерений, определяющий, какие намерения могут активизировать целевую деятельность и как система будет обрабатывать эту деятельность. Например, фильтры намерений на псевдониме деятельности могут определить флаги android:name=»android.intent.action.MAIN» и android:name=»android.intent.category.LAUNCHER», заставляя целевую деятельность загружаться при запуске приложения даже в том случае, когда в фильтрах намерений на целевой деятельности эти флаги не установлены.

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

В Android 11 появилась новая запись для работы службы в режиме Foreground (активное состояние).

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

Элемент объявляет контент-провайдера (источник данных) для управления доступом к базам данных. Все контент-провайдеры, которые являются частью приложения, должны быть представлены в элементах в файле манифеста. Если они не объявлены, они не будут работать, т.к. система их не сможет увидеть. Элемент содержит свой набор дочерних элементов для установления разрешений доступа к данным:

Этот элемент имеет много атрибутов, определяющих имя, доступность, разрешения, процесс и т. д.

Элемент является дочерним элементом для . Он определяет, для кого можно предоставить разрешения на подмножества данных контент-провайдера. Предоставление разрешения является способом допустить к подмножеству данных, предоставляемым контент-провайдером, клиента, у которого нет разрешения для доступа к полным данным. Если атрибут granturiPermissions контент-провайдера имеет значение true, то разрешение предоставляется для любых данных, поставляемых контент-провайдером. Однако, если атрибут поставлен в false, разрешение можно предоставить только подмножествам данных, которые определены этим элементом. Контент-провайдер может содержать любое число элементов .

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

Элемент определяет общедоступную библиотеку, с которой должно быть скомпоновано приложение. Этот элемент указывает системе на необходимость включения кода библиотеки в загрузчик классов для пакета приложения. Каждый проект связан по умолчанию с библиотеками Android, в которые включены основные пакеты для сборки приложений (с классами общего назначения типа Activity, Service, Intent, View, Button, Application, ContentProvider и т. д.). Однако некоторые пакеты находятся в отдельных библиотеках, которые автоматически не компонуются с приложением. Если же приложение использует пакеты из этих библиотек или других, от сторонних разработчиков, необходимо сделать явное связывание с этими библиотеками и манифест обязательно должен содержать отдельный элемент .

MDM в Android: плюсы, минусы, подводные камни

Как только у сотрудника какой-либо компании появляется необходимость выполнять задачи на мобильных устройствах (пусть даже элементарно читать рабочую почту) и, соответственно, получать с них доступ к данным компании, появляются риски. Мобильные устройства (как и все эндпоинты) подвержены ряду уязвимостей — приложения, установленные не через официальные магазины, могут оказаться вредоносными; подключение к незащищенной Wi-Fi-сети может привести к утечке данных; устройство может быть утеряно или украдено… Отсюда возникают самые популярные сценарии управления устройствами — удаленное стирание данных, ограничение на источники установки приложений, требования к используемым сетям, запрет копирования конфиденциальных данных (например, на внешний носитель) и другие.

Тут-то и появляется необходимость в MDM, или Mobile Device Management, — наборе сервисов для защиты мобильных устройств сотрудников компании.

Меня зовут Мария Глущенко, я — Android-разработчик. В этой статье расскажу, какие режимы доступны для ОС Android и как реализовывать их функционал, в чем преимущества и недостатки этих решений и как мы их используем в мобильной команде «Лаборатории Касперского».

Какие бывают управляемые режимы

Вообще существует несколько крупных решений, включающих в себя, как правило, эндпоинт-приложения для всех популярных платформ — Windows/Linux/macOS/Android/iOS, а также администраторскую консоль управления. Среди крупных вендоров можно отметить Microsoft с их Intune и VMWare с Workspace One. Про MDM в iOS можно прочитать в этой статье моего коллеги Дениса Кудинова. Я же расскажу, как обстоит дело в Android.

ОС Android предоставляет возможности задавать на устройстве разные управляемые режимы в зависимости от потребностей конкретной компании. Общепринятая градация выглядит так:

BYOD (bring your own device) — рабочие задачи могут выполняться с личного устройства сотрудника. В таком сценарии админ контролирует только рабочее пространство и не имеет доступа к персональным настройкам и данным. Это реализуется через рабочий профиль.

COPE (company owned, personally enabled) — устройства предоставляет компания, но сотрудники могут использовать их также и в личных целях. Такой сценарий может быть реализован через механизм device owner с мягкими политиками или также через рабочий профиль.

COBO (company owned, business only) — устройства предоставляет компания, и ими можно пользоваться только в рабочих целях, что достигается жесткими ограничениями на список разрешенных приложений и тому подобное. Для реализации такого сценария нужен механизм device owner.

COSU (company owned, single use; новое официальное название — dedicated devices) — так называемый режим киоска, когда на устройстве могут быть заблокированы даже домашний экран, «шторка» и настройки, а для использования доступен минимальный набор приложений (часто — только одно). Для конфигурирования киоска существует отдельный механизм.

Рассмотрим механизмы и API, позволяющие реализовать такие режимы, подробнее.

1. Device Administrator — легаси-решение для энтерпрайза, появившееся еще в Android 2.2 до того, как была придумана концепция отдельного рабочего пространства (об этом далее). Начиная с Android 9, с каждой новой версией все больше возможностей этого API помечаются как deprecated, поэтому использовать это решение напрямую в новых приложениях не рекомендуется. Однако стоит отметить, что и для последовавших более продвинутых решений Device Administrator является основой и должен быть реализован в приложении, поэтому стоит поговорить о деталях его имплементации.

How To:

● В манифесте должен быть прописан ресивер, наследующий DeviceAdminReceiver, с разрешением BIND_DEVICE_ADMIN и интент‑фильтром ACTION_DEVICE_ADMIN_ENABLED.

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

● Чтобы активировать приложение как администратора устройства, нужно отправить интент с действием ACTION_ADD_DEVICE_ADMIN и получить явное подтверждение от пользователя в диалоговом окне:

Политики, доступные для управления:

● обязательная установка пароля для устройства и различные требования к его длине и сложности;

● автоматическая блокировка устройства после определенного периода неактивности;

● дистанционное удаление данных;

● обязательное шифрование файловой системы устройства.

Пример device admin-а в манифесте:

Intent (Намерение)

Намерение (Intent) — это механизм для описания одной операции — выбрать фотографию, отправить письмо, сделать звонок, запустить браузер и перейти по указанному адресу. В Android-приложениях многие операции работают через намерения.

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

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

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

Android транслирует намерения для объявления о системных событиях, например об изменениях в состоянии сетевого подключения или в уровне заряда батареи. Системные приложения в Android, такие как программы дозвона или управления SMS, регистрируют компоненты, отслеживающие заданные намерения, например входящий звонок или получено новое SMS-сообщение, и соответствующим образом реагируют на них.

Явные намерения

Вспомним код для перехода на вторую активность в своём приложении:

 Intent intent = new Intent(HelloWorld.this, AboutActivity.class); startActivity(intent); 

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

Первый параметр – это Context. Активность является подклассом Context, поэтому мы можем использовать её как HelloWorld.this, или укороченную запись this.

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

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

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

 // У первой активности ArrayList fileList = new ArrayList(); Intent intent = new Intent(MainActivity.this, SecondActivity.class); intent.putExtra("FILES_LIST", fileList); startActivity(intent); // У второй активности ArrayList filelist = (ArrayList)getIntent().getSerializableExtra("FILES_LIST"); 

По похожему сценарию можно передать простые типы и строки.

При работе с действиями, возвращающими данные, нельзя использовать метод startActivity(), поскольку он не возвращает результат. Если вы хотите вернуть данные, то можете использовать метод startActivityForResult(), приспособленный для работы с обратными вызовами.

Неявные намерения

Существует также неявный вызов активности. В этом случае при создании намерения мы используем не имя класса, а указываем параметры action, data, category с определёнными значениями. Система анализирует, что мы тут такого понаписали и начинает подбирать подходящий вариант для запуска. Например, если указали в параметрах адрес веб-страницы, то скорее всего хотим запустить браузер и почитать новость, что Кот Ларри уволен с поста «главного мышелова» резиденции британского премьера (нехороший премьер-министр, пусть только в Москву сунется).

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

К слову сказать, мы тоже можем прописать в своей активности в фильтрах намерений (Intent Filter) набор тех же параметров: action, data, category. И тогда у пользователя может запуститься не только стандартный браузер, но и наша программа (Кот Матроскин в таких случаях говорил: Подумаешь, я еще и вышивать могу. и на машинке тоже..).

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

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

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

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

Простой пример создания намерения с предопределённым действием ACTION_VIEW для запуска браузера и перехода на нужный адрес:

 Uri address = Uri.parse("http://developer.alexanderklimov.ru"); Intent openLinkIntent = new Intent(Intent.ACTION_VIEW, address); if (openLinkIntent.resolveActivity(getPackageManager()) != null) < startActivity(openlinkIntent); >else

В данном случае действие ACTION_VIEW означает просмотр чего-либо. Мы указали нужные данные (адрес), и происходит запуск новой активности (браузера). При этом исходная активность приостанавливается и переходит в фоновый режим. Когда пользователь нажимает на кнопку Back, то он возвращается к исходной активности. Обратите внимание, что мы нигде не указываем конкретную программу-браузер типа Chrome, Opera и т.п.

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

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

Раньше я писал код без условия if и это было рабочим решением. Но следует помнить, что нет никакой гарантии, что приложение, способное обработать ваше намерение, будет установлено и доступно на устройстве. Конечно, вероятность того, что у пользователя не будет звонилки, достаточна низка. А если приложение установлено на планшете без телефонного модуля? А если появятся холодильники или стиральные машины с Android на борту? Чтобы узнать, будет ли запущена активность для вашего намерения, можно отправить запрос Менеджеру пакетов при помощи метода resolveActivity(). Поэтому в примере выше пришлось поставить дополнительную проверку. Желательно делать такую проверку во всех примерах, где-то я мог просто пропустить старый код.

Объект Intent содержит информацию, представляющую интерес для компонента, который получает намерение, и данные, которые передаются этому компоненту. Кроме того, объект Intent содержит информацию, представляющую интерес для системы Android, — имя компонента, который должен обработать намерение и набор параметров запуска этого компонента. Как правило, объект Intent может содержать следующие поля:

  • Имя компонента — имя, который должен обработать намерение. Используется объект ComponentName, который является комбинацией полного имени класса целевого компонента (например, «MainActivity») и набора имени пакета в файле манифеста приложения, где компонент постоянно находится (например, «com.samples.yourproject»). Составляющее имя является дополнительным. Если оно установлено, объект Intent поставляет образцу определяемого класса. Если имя не установлено, Android использует другую информацию в объекте Intent, чтобы определить местонахождение подходящего адресата. Составляющее имя устанавливается методами setComponent(), setClass() или setClassName() и читается методом getComponent();
  • Действие — определяет действие, которое будет выполнено. Класс Intent содержит множество констант действия. Название метода определяет ряд параметров и возвращаемое значение. Вы можете также определить собственные действия для активизации активности. В этом случае вы должны включать имя пакета приложения в качестве префикса, например com.samples.yourproject.CUSTOM_ACTiON. Действие в объекте Intent устанавливается в методе setAction() и читается методом getAction();
  • Данные — это URI данных и тип MIME для этих данных. Разные активности соединены с разными видами спецификаций данных.
  • Категория — строка, содержащая дополнительную информацию о виде компонента, который должен обработать намерение. В объект Intent можно поместить любое количество описаний категорий. Класс Intent определяет несколько констант CATEGORY, например, CATEGORY_BROWSABLE
  • Дополнения — пары ключ-значения для дополнительной информации, которую нужно поставить компоненту, обращающемуся с намерением. Например, действие ACTION_TIMEZONE_CHANGED имеет дополнение time-zone, которое идентифицирует новый часовой пояс, ACTION_HEADSET_PLUG имеет дополнение state, указывающее, включены ли наушники или отключены, а также дополнение name для типа наушников. Объект Intent имеет ряд методов put. () для вставки различных типов дополнительных данных и подобного набора методов get. () для чтения данных. Дополнения устанавливаются и читаются как объекты Bundle с использованием методов putExtras() и getExtras();
  • Флаги — указывают системе, как запускать активность (например, какому заданию должна принадлежать активность) и как обработать это после того, как активность запустили (например, принадлежит ли она списку недавних активностей). Все флаги определены в классе Intent.

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

Константы действия

  • ACTION_ANSWER — Открывает активность, которая связана с входящими звонками. Это действие обрабатывается стандартным экраном для приёма звонков;
  • ACTION_CALL — инициализирует обращение по телефону;
  • ACTION_DELETE — Запускает активность, с помощью которой можно удалить данные, указанные в пути URI внутри намерения;
  • ACTION_EDIT — Отображает данные для редактирования пользователем
  • ACTION_INSERT — Открывает активность для вставки в Курсор (Cursor) нового элемента, указанного с помощью пути URI. Дочерняя активность, вызванная с этим действием, должна вернуть URI, ссылающийся на вставленный элемент
  • ACTION_HEADSET_PLUG — Подключение наушников
  • ACTION_MAIN — Запускается как начальная активность задания
  • ACTION_PICK — Загружает дочернюю Активность, позволяющую выбрать элемент из источника данных, указанный с помощью пути URI. При закрытии должен возвращаться URI, ссылающийся на выбранный элемент. Активность, которая будет запущена, зависит от типа выбранных данных, например при передаче пути content://contacts/people вызовется системный список контактов;
  • ACTION_SEARCH — Запускает активность для выполнения поиска. Поисковый запрос хранится в виде строки в дополнительном параметре намерения по ключу SearchManager.QUERY
  • ACTION_SEND — Загружает экран для отправки данных, указанных в намерении. Контакт-получатель должен быть выбран с помощью полученной активности. Используйте метод setType, чтобы указать тип MIME для передаваемых данных. Эти данные должны храниться в параметре намерения extras с ключами EXTRA_TEXT или EXTRA_STREAM, в зависимости от типа. В случае с электронной почтой стандартное приложение в Android также принимает дополнительные параметры по ключам EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC и EXTRA_SUBJECT. Используйте действие ACTION_SEND только в тех случаях, когда данные нужно передать удаленному адресату (а не другой программе на том же устройстве)
  • ACTION_SENDTO — Открывает активность для отправки сообщений контакту, указанному в пути URI, который передаётся через намерение
  • ACTION_SYNC — Синхронизирует данные сервера с данными мобильного устройства
  • ACTION_TIMEZONE_CHANGED — Смена часового пояса
  • ACTION_VIEW — Наиболее распространённое общее действие. Для данных, передаваемых с помощью пути URI в намерении, ищется наиболее подходящий способ вывода. Выбор приложения зависит от схемы (протокола) данных. Стандартные адреса http: будут открываться в браузере, адреса tel: — в приложении для дозвона, geo: — в программе Google Maps, а данные о контакте — отображатся в приложении для управления контактной информацией
  • ACTION_WEB_SEARCH — Открывает активность, которая ведет поиск в интернете, основываясь на тексте, переданном с помощью пути URI (как правило, при этом запускается браузер)

Константы категорий

  • CATEGORY_BROWSABLE — активность может быть безопасно вызвана браузером, чтобы отобразить ссылочные данные, например, изображение или почтовое сообщение
  • CATEGORY_HOME — активность отображает Home Screen, первый экран, который пользователь видит после включения устройства и загрузки системы, или когда нажимает клавишу HOME
  • CATEGORY_LAUNCHER — активность может быть начальной деятельностью задания из списка приложений в группе Application Launcher устройства

Методы

Для работы с категориями в классе Intent определена группа методов:

  • addCategory() — помещает категорию в объект Intent
  • removeCategory() — удаляет категорию, которая была добавлена ранее
  • getCategories() — получает набор всех категорий, находящихся в настоящее время в объекте Intent

Фильтры намерений и запуск заданий

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

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

В фильтре намерений декларируется только три составляющих объекта Intent: действие, данные, категория. Дополнения и флаги не играют никакой роли в принятии решения, какой компонент получает намерение.

Например, в любом приложении есть главная активность, которая устанавливается как точка входа для задания:

Фильтр такого вида в элементе помечает активность, как запускаемую по умолчанию. Элемент заставляет значок и метку для деятельности отображаться на панели Application Launcher, давая пользователям возможность запускать задание и возвращаться к этому заданию в любое время после того, как оно было запущено.

Внутри узла Фильтра намерений можно использовать такие теги (и соответствующие атрибуты).

  • action — Использует атрибут android:name, чтобы задать название действия, которое будет обслуживаться. Каждый фильтр намерений должен иметь один (и только один) тег action. Действия должны быть представлены в виде уникальных строк, которые сами себя описывают. Рекомендуется выбирать названия, основываясь на соглашении об именовании пакетов в Java.
  • сategory — Использует атрибут android:name, чтобы указать, при каких обстоятельствах должно обслуживаться действие. Каждый тег intent-filter способен содержать несколько тегов category. Вы можете задать собственные категории или же брать стандартные значения, предоставляемые системой
    • ALTERNATIVE — Наличие данной категории говорит о том, что действие должно быть доступно в качестве альтернативного тому, которое выполняется по умолчанию для элемента этого типа данных. Например, если действие по умолчанию для контакта — просмотр, то в качестве альтернативы его также можно редактировать
    • SELECTED_ALTERNATIVE — То же самое, что и ALTERNATIVE, но вместо одиночного действия с использованием утверждения намерения, которое описано выше, применяется в тех случаях, когда нужен список различных возможностей. Одной из функций фильтра намерений может стать динамическое заполнение контекстного меню с помощью действий.
    • BROWSABLE — Говорит о том, что действие доступно из браузера. Когда намерение срабатывает в браузере, оно всегда содержит данную категорию. Если вы хотите, чтобы приложение реагировало на действия, инициированные браузером (такие как перехват ссылок на конкретный сайт), то должны добавить в его манифест категорию BROWSABLE.
    • DEFAULT — Установите эту категорию, чтобы сделать компонент обработчиком по умолчанию для действия, выполняемого с указанным типом данных внутри Фильтра намерений. Это необходимо и для Активностей, которые запускаются с помощью явных Намерений
    • GADGET — Наличие этой категории указывает на то, что данная активность может запускаться внутри другой активности.
    • HOME — Устанавливая эту категорию и не указывая при этом действия, вы создаете альтернативу для стандартного домашнего экрана.
    • LAUNCHER — Используя эту категорию, вы помещаете Активность в окно для запуска приложений.
    • android:host — задаёт доступное имя удалённого сервера (например, google.com);
    • android:mimetype — позволяет указать тип данных, которые ваш компонент способен обрабатывать. Для примера: будет соответствовать любому Курсору в Android;
    • android:path — задает доступные значения для пути URI (например, /transport/boats/);
    • android:port — указывает доступные порты для заданного сервера;
    • android:scheme — требует указать конкретную схему (например, content или http).

    Принцип работы фильтров намерений

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

    1. Android собирает список всех доступных Фильтров намерений из установленных пакетов.
    2. Фильтры, которые не соответствуют действию или категории Намерения, удаляются из списка. Совпадение происходит только в том случае, если Фильтр намерений содержит указанное действие (или если действие для него вовсе не задано). Совпадения не произойдёт, только если ни одно из действий Фильтра намерений не будет эквивалентно тому, которое задано в Намерении. Для категорий процесс соответствия более строгий. Фильтр намерений должен включать в себя все категории, заданные в полученном Намерении. Фильтр, для которого категории не указаны, может соответствовать только таким же Намерениям (нет категорий).
    3. Наконец, каждая часть пути URI из Намерения сравнивается с тегом data Фильтра намерений. Если в Фильтре указаны схема (протокол), сервер/принадлежность, путь или тип MIME, все эти значения проверяются на соответствие пути URI из Намерения. При любом несовпадении Фильтр будет удален из списка. Если в Фильтре намерений не указано ни одного параметра data, его действие будет распространяться на любые данные.
      • MIME — тип данных, который должен совпасть. При сравнении типов данных вы можете использовать маски, чтобы охватывать все подтипы (например, cats/*). Если в Фильтре намерения указан тип данных, он должен совпасть с тем, который значится в намерении, при отсутствии тега data подойдет любой тип.
      • Схема — это протокольная часть пути URI, например http:, mailto: или tel:.
      • Имя сервера (или принадлежность данных) — часть URI между схемой и самим путём (например, www.google.com). Чтобы совпало имя сервера, схема Фильтра намерений также должна подойти.
      • После имени сервера идёт путь к данным (например, /ig). Путь пройдёт проверку только после схемы и имени сервера, содержащихся в теге.
    4. Когда вы неявным образом запускаете Активность и вышеописанный процесс возвращает более одного совпадения, пользователю выводится список со всеми вариантами

    Поиск и использование намерения, с помощью которого была запущена активность

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

    Используйте метод getIntent() (как правило, внутри метода onCreate()), чтобы извлечь намерение, с помощью которого компонент запущен.

     @Override public void onCreate(Bundle savedInstanceState)

    Применяйте методы getAction() и getData(), чтобы найти действие и данные, связанные с намерением. Для извлечения дополнительной информации, хранящейся в параметре extras, используйте типизированные методы getExtra.

     String action = intent.getAction(); Uri data = intent.getData(); 

    Делегирование ответственности

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

     Intent intent = getIntent(); if (isDuringBreak) startNextMatchingActivity(intent); 

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

    ACTION_PICK

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

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

    Следующий код выведет диалоговое окно со списком всех возможных программ, которые могут запустить активность с данными, так как мы не указываем конкретный тип (setType(«*/*»)):

     // Показываем все программы для запуска Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("*/*"); startActivityForResult(intent, 1); 

    Если мы укажем конкретный тип данных, которые нас интересует, то список программ существенно сузится. Например, если указать intent.setType(«image/*»);, то можем увидеть только системную программу Галерея для просмотра картинок (у пользователя могут быть установлены программы, которые также предназначены для просмотра картинок, поэтому список может отличаться).

    ACTION_SEND

    Очень распространённое намерение. Используйте метод setType(), чтобы указать тип MIME для передаваемых данных. Эти данные должны храниться в параметре намерения extras с ключами EXTRA_TEXT или EXTRA_STREAM, в зависимости от типа. В случае с электронной почтой стандартное приложение в Android также принимает дополнительные параметры по ключам EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC и EXTRA_SUBJECT.

    Если есть установленное приложение с фильтром, который соответствует ACTION_SEND и MIME-типу text/plain, система Android запустит его, а если будет найдено более одного приложения, то система отобразит диалог выбора, который позволяет пользователю выбрать приложение.

    Если ваша активность хочет обрабатывать подобные намерения, то она должна содержать следующие данные:

    Имя сообщает Android, что активность может обрабатывать ACTION_SEND.

    Фильтр должен включать категорию DEFAULT, в противном случае он не сможет получать неявные намерения.

    Указываем типы данных, которые могут обрабатываться активностью.

    ACTION_GET_CONTENT

    Выбрать файл

    Если вы не хотите писать собственный менеджер файлов, а готовы использовать готовые приложения для выбора файла, то можете использовать следующий код:

     public class PickFileActivity extends Activity < TextView textView; private static final int PICKFILE_RESULT_CODE = 1; @Override public void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.main); Button buttonPick = findViewById(R.id.buttonpick); textView = findViewById(R.id.textView); buttonPick.setOnClickListener(new Button.OnClickListener()< @Override public void onClick(View arg0) < Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("file/*"); startActivityForResult(intent,PICKFILE_RESULT_CODE); >>); > @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) < switch(requestCode)< case PICKFILE_RESULT_CODE: if(resultCode == RESULT_OK)< String FilePath = data.getData().getPath(); textView.setText(FilePath); >break; > > > 

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

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

     @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) < switch(requestCode)< case PICKFILE_RESULT_CODE: if(resultCode == RESULT_OK)< String FilePath = data.getData().getPath(); String FileName = data.getData().getLastPathSegment(); int lastPos = FilePath.length() - FileName.length(); String Folder = FilePath.substring(0, lastPos); textFile.setText("Full Path: \n" + FilePath + "\n"); textFolder.setText("Folder: \n" + Folder + "\n"); textFileName.setText("File Name: \n" + FileName + "\n"); >break; > > 

    Диалоговое окно выбора

    При выборе из списка программ пользователь может выбрать программу по умолчанию, которая будет автоматически запускаться при выбранном намерении. В этом случае диалоговое окно выводиться не будет. Но можно принудительно выводить диалоговое окно при помощи метода createChooser() и пользователю придётся каждый раз выбирать нужную активность:

     Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, messageText); Intent chosenIntent = Intent.createChooser(intent, "Заголовок в диалоговом окне"); startActivity(chosenIntent); 

    Если на устройстве не будет подходящих активностей для запуска, то createChooser() обработает данную ситуацию и выведет соответствующее сообщение. В этом заключается его преимущество. Если передать методу startActivity() намерение, для которого не найдётся подходящей активности, то возникнет исключение ActivityNotFoundException. И вам придётся перехватывать его в блоке try/catch, чтобы избежать аварийного завершения приложения.

    Android 12

    В Android 12 немного изменились правила для фильтров к намерениями. Если их игнорировать, то можно получить ошибку в запуске приложения. Основное изменение — нужно явно указать атрибут androd:exported со значениями true или false у , , , , которые имеют в своём составе intent-filter.

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

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

    Другие примеры использования намерений

    Запустить другую активность вашего приложения можно не только стандартным способом, о котором говорится в первом курсе, но и другим немного странным способом. Прописываем в манифесте у второй активности мета-данные:

    Запускаем активность по щелчку кнопки.

     Intent intent = new Intent("ru.alexanderklimov.helloworld.second.SECOND"); // intent.putExtra("something", 2); // по желанию startActivity(intent); 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *