Этот урок научит вас
- Ответить на запрос отображения данных
- Запросить права доступа
- Получить каталог со скопированными файлами
Вы также должны прочитать
Передача файлов Android Beam копирует файлы в отдельный каталог на принимающем устройстве. Он также сканирует скопированные файлы с помощью Анализатора Медиа-файлов Android, и добавляет записи для медиа-файлов вMediaStore
. Этот урок покажет вам, как реагировать, когда копирование файла будет завершено, и, как найти скопированные файлы на принимающем устройстве.[wpanchor id=»1″]
Ответить на запрос отображения данных
Когда передача файлов Android Beam заканчивает копирование файлов на принимающем устройстве, она посылает уведомление, содержащее Intent
с действием ACTION_VIEW
, MIME-типом первого файла, передача которого завершилась, и URI, который указывает на первый файл. Когда пользователь нажимает на уведомление, это интент посылается в систему. Чтобы ваше приложение могло ответить на это интент, добавьте <intent-filter>
элемент для <activity>
элементаActivity
, которая должна реагировать. В <intent-filter>
элемент, добавьте следующие дочерние элементы:
<action android:name="android.intent.action.VIEW" />
- Соответствует
ACTION_VIEW
интенту, отправленному уведомлением. <category android:name="android.intent.category.CATEGORY_DEFAULT" />
- Соответствует
Intent
, который не имеет явной категории. <data android:mimeType="mime-type" />
- Соответствует MIME-типу. Укажите только те типы, которые ваше приложение может обрабатывать.
Например, следующий фрагмент показывает, как добавить фильтр интентов, который запускает деятельность com.example.android.nfctransfer.ViewActivity
:
<activity android:name="com.example.android.nfctransfer.ViewActivity" android:label="Android Beam Viewer" > ... <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> ... </intent-filter> </activity>
Примечание: Передача файлов Android Beam не единственный источник ACTION_VIEW
интента. Другие приложения на принимающем устройстве могут также отправлять Intent
с этим действием. Обработка этой ситуации обсуждается в разделе Получить каталог из URI контента.[wpanchor id=»2″]
Запросить права доступа
Чтобы прочитать файлы, которые передача файлов Android Beam копирует на устройство, запросите разрешение READ_EXTERNAL_STORAGE
. Например:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Если вы хотите скопировать переданные файлы в собственное хранилище вашего приложения, запросите вместо этого разрешение WRITE_EXTERNAL_STORAGE
. WRITE_EXTERNAL_STORAGE
включает в себя READ_EXTERNAL_STORAGE
.
Примечание: В Android 4.2.2 (API уровень 17), разрешение READ_EXTERNAL_STORAGE
проверяется только если пользователь хочет это делать. Будущие версии платформы возможно будут требовать данное разрешение для всех случаев. Для обеспечения прямой совместимости, запросите разрешения сейчас, прежде чем оно будет требоваться.
Поскольку ваше приложение контролирует свою областью внутреннего хранилища, вы не должны просить разрешение на запись для копирования переданного файла в вашу область внутреннего хранилища.[wpanchor id=»3″]
Получить каталог со скопированными файлами
Передача файлов Android Beam копирует все файлы внутри одной передачи в один каталог на принимающем устройстве. URI в содержании Intent
, присланном уведомлением передачи файлов Android Beam, указывает на первый переданный файл. Тем не менее, ваше приложение может также получить ACTION_VIEW
намерение из другого источника, а не от передачи файлов Android Beam. Чтобы определить, как следует обрабатывать входящий Intent
, вам необходимо проверить схему и авторитетный источник.
Чтобы получить схему для URI, вызовите Uri.getScheme()
. Следующий фрагмент кода показывает, как определить схему и обработать URI соответственно:
public class MainActivity extends Activity { ... // A File object containing the path to the transferred files private File mParentPath; // Incoming Intent private Intent mIntent; ... /* * Called from onNewIntent() for a SINGLE_TOP Activity * or onCreate() for a new Activity. For onNewIntent(), * remember to call setIntent() to store the most * current Intent * */ private void handleViewIntent() { ... // Get the Intent action mIntent = getIntent(); String action = mIntent.getAction(); /* * For ACTION_VIEW, the Activity is being asked to display data. * Get the URI. */ if (TextUtils.equals(action, Intent.ACTION_VIEW)) { // Get the URI from the Intent Uri beamUri = mIntent.getData(); /* * Test for the type of URI, by getting its scheme value */ if (TextUtils.equals(beamUri.getScheme(), "file")) { mParentPath = handleFileUri(beamUri); } else if (TextUtils.equals( beamUri.getScheme(), "content")) { mParentPath = handleContentUri(beamUri); } } ... } ... }
Получить каталог из URI файла
Если входящий Intent
содержит URI файла, URI содержит абсолютное имя файла, в том числе полный путь к каталогу и имя файла. Для передача файлов Android Beam, путь к каталогу указывает на расположение других передаваемых файлов, если таковые имеются. Чтобы получить путь к каталогу, получите часть URI относящуюся к пути, которая содержит весь URI, кроме file:
префикса. Создайте File
из это части, содержащей путь, а затем получите путь к каталогу из родительского File
:
... public String handleFileUri(Uri beamUri) { // Get the path part of the URI String fileName = beamUri.getPath(); // Create a File object for this filename File copiedFile = new File(fileName); // Get a string containing the file's parent directory return copiedFile.getParent(); } ...
Получить каталог из URI контента
Если входящий Intent
содержит URI контента, URI может указывать на каталог и имя файла, сохраненного в MediaStore
поставщике контента. Вы можете определить URI контента дляMediaStore
путем проверки авторитетного источника данного URI. URI контента для MediaStore
может прийти от передачи файлов Android Beam или из другого приложения, но в обоих случаях вы можете получить имя каталога и файла для этого URI.
Вы также можете принять входящее ACTION_VIEW
интент содержащее URI контента для другого контент-провайдера, а не только для MediaStore
. В этом случае, URI контента не содержитMediaStore
в имени авторитетного источника, и URI контента обычно не указывают на каталог.
Примечание: Для передачи файлов Android Beam, вы получаете URI контента в ACTION_VIEW
интент, если первый входящий файл имеет MIME-тип «audio/*», «image/*», или «video/*», указывая, что файл является медиафайлом. Передача файлов Android Beam индексирует медиафайлы, запуская Меди Анализатор для каталога, в котором он хранит передаваемые файлы. Сканер файлов записывает результаты в MediaStore
контент-провайдер, а затем он передает URI контента первого файла обратно в передачу файлов Android Beam. Этот тот URI контента, который вы получите в уведомлении Intent
. Для получения каталога первого файла, извлеките его из MediaStore
используя URI контента.
Определить поставщика контента
Чтобы определить, можно ли получить каталог файла из содержимого URI, определите контент-провайдера, связанного с URI, вызвав Uri.getAuthority()
для получения авторитетного источника. Есть два возможных значения:
MediaStore.AUTHORITY
- URI для файла или файлов, отслеживаемого
MediaStore
. Получите полное имя файла изMediaStore
, и получите каталог из имени файла. - Любое другое значение авторитетного источника
- URI контента от другого провайдера контента. Отобразите данные, связанные с URI контента, но не получайте из него каталог.
Чтобы получить каталог для MediaStore
URI контента, выполните запрос, который задает входящий URI контента в качестве Uri
аргумента и столбец MediaColumns.DATA
для отображения. Возвращенный Cursor
содержит полный путь и имя файла, представленного URI. Этот путь также содержит все другие файлы, которые передача файлов Android Beam просто скопировала на устройство.
Следующий фрагмент показывает, как проверить авторитетный источник URI контента и получить путь и имя файла для перемещенного файла:
... public String handleContentUri(Uri beamUri) { // Position of the filename in the query Cursor int filenameIndex; // File object for the filename File copiedFile; // The filename stored in MediaStore String fileName; // Test the authority of the URI if (!TextUtils.equals(beamUri.getAuthority(), MediaStore.AUTHORITY)) { /* * Handle content URIs for other content providers */ // For a MediaStore content URI } else { // Get the column that contains the file name String[] projection = { MediaStore.MediaColumns.DATA }; Cursor pathCursor = getContentResolver().query(beamUri, projection, null, null, null); // Check for a valid cursor if (pathCursor != null && pathCursor.moveToFirst()) { // Get the column index in the Cursor filenameIndex = pathCursor.getColumnIndex( MediaStore.MediaColumns.DATA); // Get the full file name including path fileName = pathCursor.getString(filenameIndex); // Create a File object for the filename copiedFile = new File(fileName); // Return the parent directory of the file return new File(copiedFile.getParent()); } else { // The query didn't work; return null return null; } } } ...
Чтобы узнать больше о получении данных от поставщика информации, см. раздел Получение данных от поставщика.