Статьи

Android SDK: получение данных из намерения отправки

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


Начните с создания нового проекта Android в Eclipse. Выберите «Файл», «Новый», «Проект» — выберите «Проект приложения Android» и нажмите «Далее». В окне «Новое приложение для Android» введите выбранные имена приложений, проектов и пакетов, а затем нажмите «Далее».

Новый проект Android

В окне конфигурации проекта выберите ваши параметры, позволяя Eclipse создать Activity для вас. На следующих экранах настройте значок запуска в случае необходимости, а затем выберите «Пустое действие». На экране «Настройка действия» введите имя действия и затем выберите «Готово».

Пустая активность

Eclipse должен создать файлы активности и макета для вашего приложения.


Чтобы ваше приложение появилось в списке выбора, представленном, когда пользователь пытается поделиться данными из другого приложения, вам нужно изменить файл Project Manifest. Откройте его в Eclipse и переключитесь на вкладку редактора XML. Найдите раздел, содержащий основную активность вашего приложения — вы уже должны увидеть там элемент Intent Filter, указывающий действие MAIN и категорию LAUNCHER.

После существующего элемента Intent Filter, внутри основного элемента Activity добавьте еще один Intent Filter:

1
2
3
<intent-filter>
 
</intent-filter>

Здесь мы определяем действия, которые могут запускать приложение — существующий фильтр намерений, определяющий обычные параметры, когда пользователь запускает приложение с домашнего экрана или из меню приложения устройства. Добавляя еще один элемент Intent Filter, мы указываем дополнительные параметры для запуска приложения. Внутри нового элемента добавьте элемент Action, указывающий действие SEND Intent:

1
<action android:name=»android.intent.action.SEND» />

Это говорит Android, что когда другие приложения запускают SEND Intent, это приложение может получать то, что им передается. Теперь назначьте Intent Filter категорию:

1
<category android:name=»android.intent.category.DEFAULT» />

Далее нам нужно указать типы MIME, которые получит приложение:

1
2
<data android:mimeType=»image/*» />
<data android:mimeType=»text/*» />

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

Вот приложение «DataReceiver», которое отображается в списке общего доступа для приложения «Галерея», с помощью которого можно передавать изображения различных типов.

Приложение в списке Share

Давайте разработаем приложение для отображения полученной текстовой строки или изображения. Откройте основной файл макета и перейдите на вкладку XML для редактирования кода. Замените любой существующий код в файле макета следующим контуром относительной компоновки:

1
2
3
4
5
6
7
8
<RelativeLayout xmlns:android=»http://schemas.android.com/apk/res/android»
    xmlns:tools=»http://schemas.android.com/tools»
    android:layout_width=»match_parent»
    android:layout_height=»match_parent»
    android:padding=»10dp»
    tools:context=».DataReceiverActivity» >
 
</RelativeLayout>

Измените атрибут «tools: context», если вы выбрали другое имя класса Activity. Внутри макета добавьте следующее для отображения полученного изображения:

1
2
3
4
5
6
<ImageView
    android:id=»@+id/picture»
    android:layout_width=»fill_parent»
    android:layout_height=»fill_parent»
    android:contentDescription=»@string/pic»
/>

Мы будем использовать идентификатор для обращения к представлению изображения в нашей активности Java, обновляя его для отображения любого изображения, полученного из намерения SEND. Добавьте указанную строку в файл res / values ​​/ strings.xml вашего приложения:

1
<string name=»pic»>Received Picture</string>

Вернувшись в файл макета, добавьте текстовое представление, чтобы отобразить любые текстовые строки, полученные с помощью SEND Intent:

1
2
3
4
5
<TextView
    android:id=»@+id/txt»
    android:layout_width=»fill_parent»
    android:layout_height=»fill_parent»
/>

Опять же, у нас есть атрибут ID, который мы можем использовать в коде Java.


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

1
2
3
4
5
6
7
8
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

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

1
2
3
4
//get the image view
ImageView picView = (ImageView)findViewById(R.id.picture);
//get the text view
TextView txtView = (TextView)findViewById(R.id.txt);

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

1
2
//get the received intent
Intent receivedIntent = getIntent();

Теперь мы можем использовать это, чтобы также получить Действие, которое использовалось при запуске Действия:

1
2
//get the action
String receivedAction = receivedIntent.getAction();

Это позволит нам определить, запущено ли приложение из меню устройства или из списка общего доступа. Если приложение было запущено с действием SEND, в намерении, которое его запустило, также будет указан тип MIME. Получите это следующим образом:

1
2
//find out what we are dealing with
String receivedType = receivedIntent.getType();

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

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

Меню браузера

Вот приложение, указанное в списке общего доступа к браузеру:

Приложение в списке браузеров

Теперь у нас есть две возможности: приложение было запущено с устройства по умолчанию и не получает никаких входящих данных; приложение было запущено для обмена контентом, в этом случае поступает либо текстовая строка, либо изображение. Добавьте условный оператор в onCreate для обработки этих двух сценариев:

1
2
3
4
5
6
7
//make sure it’s an action and type we can handle
if(receivedAction.equals(Intent.ACTION_SEND)){
    //content is being shared
}
else if(receivedAction.equals(Intent.ACTION_MAIN)){
    //app has been launched directly, not from share list
}

Если вы посмотрите на свой файл Manifest, то увидите, что это Действия, включенные в два элемента Intent Filter для Activity. Давайте сначала завершим оператор ACTION_MAIN else if, так как он проще. Здесь вам нужно включить все, что вы хотите, чтобы ваше приложение делало, когда ничего не было передано ему. Для целей этого урока мы просто отобразим текстовую строку в текстовом представлении:

1
txtView.setText(«Nothing has been shared!»);

Теперь к оператору ACTION_SEND if , в котором нам нужно обрабатывать полученные данные типов MIME, которые мы перечислили в манифесте. Сначала добавьте условие для обработки двух перечисленных нами типов: текста и изображений:

1
2
3
4
5
6
if(receivedType.startsWith(«text/»)){
    //handle sent text
}
else if(receivedType.startsWith(«image/»)){
    //handle sent image
}

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


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

1
2
//hide the other ui item
picView.setVisibility(View.GONE);

Теперь извлеките строку как дополнительный из намерения:

1
2
//get the received text
String receivedText = receivedIntent.getStringExtra(Intent.EXTRA_TEXT);

Мы используем метод getStringExtra для текстовых данных, передавая константу намерения EXTRA_TEXT для получения любой последовательности символов, переданной с помощью действия SEND. Теперь давайте удостоверимся, что у нас есть некоторые данные и отображаем их в пользовательском интерфейсе приложения:

1
2
3
4
5
//check we have a string
if (receivedText != null) {
    //set the text
    txtView.setText(receivedText);
}

Вы можете, конечно, выполнить дальнейшую обработку текста, если вам нужно — это текстовый URL, общий доступ из браузера:

Общий текст в пользовательском интерфейсе приложения

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

1
2
//hide the other ui item
txtView.setVisibility(View.GONE);

Теперь нам нужно получить URI изображения, так как это то, чем будет делиться Intent:

1
2
//get the uri of the received image
Uri receivedUri = (Uri)receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM);

На этот раз мы используем метод getParcelableExtra — существует множество других методов Intent для различных типов данных, которые вы можете получать в своих приложениях, включая типы чисел, массивы и списки. На этот раз мы передаем константу намерения EXTRA_STREAM, которая используется для получения данных, отличных от текста. Теперь мы можем использовать URI изображения в приложении — приведенный ниже пример кода просто отображает его в представлении «Изображение», но если вы планируете получать изображения в своих собственных приложениях, вам следует сначала выполнить повторную выборку данных изображения, чтобы избежать проблем с памятью:

1
2
3
4
5
6
//check we have a uri
if (receivedUri != null) {
    //set the picture
    //RESAMPLE YOUR IMAGE DATA BEFORE DISPLAYING
    picView.setImageURI(receivedUri);//just for demonstration
}

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

Вот изображение, переданное из приложения Галерея:

Общее изображение в пользовательском интерфейсе приложения

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