Важно (9.07.22)

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

понедельник, 12 мая 2014 г.

Intent: Open File или как открыть файл в приложении по умолчанию

Частенько на разных форумах всплывают вопросы об открытии файлов в приложении (ях) по умолчанию. Решил разъяснить немного ситуацию. Про сами Intent рассказывать не буду, т.к. есть очень хорошая статья (Delphi XE5: использование Intent (намерения) в Android), в которой объясняется принцип работы с интентами и имеется парочка примеров, остальные подробности вы всегда можете найти в справке Android API.









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

Пример №1 – откроем картинку «picture.png», которая лежит в папке «Download»
uses
  System.IOUtils, FMX.Helpers.Android, Androidapi.Helpers,
  Androidapi.JNI.GraphicsContentViewText;

procedure TForm1.Button1Click(Sender: TObject);
var
  Intent: JIntent;
begin
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setDataAndType(StrToJURI('file:' + TPath.Combine(TPath.GetSharedDownloadsPath, 'picture.png')), StringToJString('image/png'));
  SharedActivity.startActivity(Intent);
end;

Самая интересная строка:
Intent.setDataAndType(StrToJURI('file:' + TPath.Combine(TPath.GetSharedDownloadsPath, 'picture.png')), StringToJString('image/png'));

В этой строке мы указываем:
  • полный путь до файла, при этом, не забывая добавить в начало 'file:', без этого Android не поймет, что вы открываете файл
  • вторым параметром идёт указание MIME Type (ниже вы найдёте список самых популярных типов, а также вариант с автоматическим определением)

Также можно указывать неполный MIME тип, например, так «image/*», «video/*» и т.п.

Таблица соответствия «расширение = MIME Type»:
Расширение MIME Type
Android Application .apk application/vnd.android.package-archive
Text .txt text/plain
.csv text/csv
.xml text/xml
Web related .htm text/html
.html text/html
.php text/php
Image .png image/png
.gif image/gif
.jpg image/jpg
.jpeg image/jpeg
.bmp image/bmp
Audio .mp3 audio/mp3
.wav audio/wav
.ogg audio/x-ogg
.mid audio/mid
.midi audio/midi
.amr audio/AMR
Video .mpeg video/mpeg
.3gp video/3gpp
Package .jar application/java-archive
.zip application/zip
.rar application/x-rar-compressed
.gz application/gzip


В Google уже позаботились об определении MIME типов и создали карту «расширение = MIME type»(Android API: android.webkit.MimeTypeMap ), нам остаётся только воспользоваться ей, а точнее её методами. 
Для того, чтобы методы работали, необходимо добавить в uses модуль: «Androidapi.JNI.Webkit»

Шаги:
  1. Получаем расширение файла (без точки)
  2. Получаем экземпляр карты
  3. Получаем MIME type

Пример №2с автоматическим определением MIME Type по расширению файла.
uses
  System.IOUtils, FMX.Helpers.Android, Androidapi.JNI.JavaTypes,
  Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Webkit;

procedure TForm1.Button1Click(Sender: TObject);
var
  ExtFile: string;
  mime: JMimeTypeMap;
  ExtToMime: JString;
  Intent: JIntent;
begin

  ExtFile := 'png';
  mime := TJMimeTypeMap.JavaClass.getSingleton();
  ExtToMime := mime.getMimeTypeFromExtension(StringToJString(ExtFile));

  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setDataAndType(StrToJURI('file:' + TPath.Combine(TPath.GetSharedDownloadsPath, 'picture.png')), ExtToMime);
  SharedActivity.startActivity(Intent);
end;


На этом всё. Спасибо за внимание.