Перейти к содержанию
  • Регистрация
  • 0
Alexey

Как открыть PDF в стандартном приложении просмотра PDF файлов?

Вопрос

На платформе ios PDF открываются как обычные html страницы. Как открыть PDF в браузере на android?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендуемые сообщения

  • 0

Открытие любого файла в подходящем приложении в операционной системе Андроид выполняются одинаковым способом.

  1. Путем посылки намерения (Интент) с указанием файла и типа данных.
  2. Далее система ищет по указанному типу файла, какие приложения зарегистрированы на обработку файлов этого типа,
  3. Если приложение, которое может обработать этот файл, одно, то запускает активити приложения и передает туда ваш файл/данные.
  4. Если приложений несколько - запускает диалоговое окно выбора приложения, которое будет выполнять обработку вашего файла.

Резюмируя это, смотрим на код:

uses
  System.IOUtils, FMX.Helpers.Android, Androidapi.JNI.Net, Androidapi.JNI.GraphicsContentViewText;

procedure TForm7.btnOpenPDFClick(Sender: TObject);
const
  SAMPLE_PDF_FILENAME = 'example.pdf';
var
  Uri: Jnet_Uri;
  OpenLinkIntent: JIntent;
  PDFFileName: string;
begin
  PDFFileName := TPath.Combine(TPath.GetDocumentsPath, SAMPLE_PDF_FILENAME);  { Внутренний доступ}
  Uri := StrToJURI(PDFFileName);
  // Формируем намерение об открытии файла в стандартном приложении
  OpenLinkIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, Uri);
  // Устанавливаем тип данных
  OpenLinkIntent.setType(StringToJString('application/pdf'));
  OpenLinkIntent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_CLEAR_TOP);
  // Запускаем приложение и передаем ему наше намерение
  try
    SharedActivity.startActivity(OpenLinkIntent);
  except on E: Exception do
    ShowMessage('Не удалось открыть PDF. В системе нет доступных приложения для просмотра pdf');
  end;
end;

В этом код pdf файл берется из самого пакета приложения (я включил pdf файл в пакет приложения).

Если вам нужно вытащить файл в любом другом месте, просто укажите в PDFFileName полный путь к файлу в файловой системе вашего устройства.

 

Проект доступен тут: OpenPDF.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Добрый день!

 

При выполнении вышеуказанного проекта наблюдаю следующую картину - открывается PDF Reader, но не открывает сам запрашиваемый файл. С чем может быть связано такое поведение. Описанная ситуация наблюдается на телефоне и планшете.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Отвечу сам, следующие изменения позволили нормально просматривать PDF:

1. Открыть PDF удалось только из внешнего хранилища, иначе PDF Reader ругался на недопустимое имя файла.

2. Имя файла должно начинаться с file:

3. setType сбрасывал установленный Uri на файл данных, поэтому нужно использовать setDataAndType

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

А как в ios открыть файл(например картинку) в стандартном приложении? Или через браузер сработает как NSUrl?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Виталий просьба осветить вопрос поподробнее.

1. Что за внешнее хранилище ? Какой путь нужно ставить в деплоймент менеджере и какую функцию использовать для поиска файла ( GetDocumentsPath или GetSharedDocumentsPath) ?

2. Если у файла имя myDoc.pdf   Нужно ли указать : AFileName =  System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetSharedDocumentsPath(), L"file:MyDoc.pdf"); или как-то иначе ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, chaplin.u@gmail.com сказал:

Виталий просьба осветить вопрос поподробнее.

1. Что за внешнее хранилище ? Какой путь нужно ставить в деплоймент менеджере и какую функцию использовать для поиска файла ( GetDocumentsPath или GetSharedDocumentsPath) ?

2. Если у файла имя myDoc.pdf   Нужно ли указать : AFileName =  System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetSharedDocumentsPath(), L"file:MyDoc.pdf"); или как-то иначе ?

 

внешнее хранилище это карта памяти скорее всего.

папка GetDocumentsPath - доступна только для своего приложения, соответственно сторонние приложения доступа не имеют к ней

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Оказалось что нужно класть в общедоступные папки а это чревато удалением нужного файла. А как в случае отсутствия файла дать ссылку на скачивание и запуск скаченного файла ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

выход можно сделать такой

1) оригинал всегда лежит в GetDocumentsPath. 

2) если его нужно открыть в сторонней программе, копируем в Download и передаем этот путь сторонней программе

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 1
function GetDefaultFilePath(const FileName: string): string;
begin
{$IFDEF Android}
  Result := TPath.Combine(TPath.GetSharedDocumentsPath, FileName);
{$ENDIF}
{$IFDEF IOS}
  Result := TPath.Combine(TPath.GetDocumentsPath, FileName);
{$ENDIF}
{$IFDEF MSWindows}
  Result := TPath.Combine(TPath.GetDocumentsPath, FileName);
{$ENDIF}
  ForceDirectories(ExtractFilePath(Result));
end;

procedure TForm.ShowPDF;
var
{$IFDEF Android}
  Intent: JIntent;
{$ENDIF}
  FilePath, tmpStr: string;
begin
  FilePath := GetDefaultFilePath(Filename);

{$IFDEF Android }
  try
    Intent := TJIntent.Create;
    Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
    Intent.setDataAndType(StrToJURI('file:' + FilePath),
      StringToJString('application/pdf'));
    Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NO_HISTORY);
    Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
    SharedActivity.startActivity(Intent);
  except
    on E: Exception do
      ShowToast(E.Message);
  end;

{$ENDIF}
{$IFDEF IOS}
  wbViewPDF.Visible := True;
  wbViewPDF.URL := 'file:/' + FilePath;
{$ENDIF}
end;

Приблизительно так...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

на андроиде всё работает а вот АйОся не знает что такое wbViewPDF. и кстати гугл тоже ....

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

спасибо .  

в Андроиде есть интенты а как на  IOS  запустить  например просмотр видео файла ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 1
18 минут назад, chaplin.u@gmail.com сказал:

спасибо .  

в Андроиде есть интенты а как на  IOS  запустить  например просмотр видео файла ?

на ios нету интентов, там все делается через url. открываете url и система сама откроет приложение если такое установлено

modURL.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

тогда вопрос - почему для PDF нужно использовать TWebBrowser  а не  url ? Ведь PDF в IOS  родной формат ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
9 минут назад, chaplin.u@gmail.com сказал:

тогда вопрос - почему для PDF нужно использовать TWebBrowser  а не  url ? Ведь PDF в IOS  родной формат ?

незнаю, видать так удобно было. даже если открыть pdf в браузере Сафари предлагает открыть его в iBooks

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

когда открыл TWebBrowser  понял в чём разница. он же видимый. т.е у него есть окно в которое он выводит информацию а url открывает в отдельном окне.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 минуту назад, chaplin.u@gmail.com сказал:

когда открыл TWebBrowser  понял в чём разница. он же видимый. т.е у него есть окно в которое он выводит информацию а url открывает в отдельном окне.

эмм, на андроиде тоже откроется в отдельном окне...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

фигня получается. так как код :  wbViewPDF.Visible := True;  делает видимым броузер

и он успешно открывает файл но закрыть его уже никак ! 

а методы открытия файла как ссылку не работает....

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

А у меня вообще что-то не получается...

Пишет - не получается открыть файл.

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

 

 

procedure TForm7.btnOpenPDFClick(Sender: TObject);
const
  SAMPLE_PDF_FILENAME = '978.pdf';
var
  Uri: Jnet_Uri;
  OpenLinkIntent: JIntent;
  PDFFileName: string;
  sr:TSearchRec;
  bchars, Tws:TSysCharSet;
begin
PDFFileName :=TPath.Combine(TPath.GetSharedDownloadsPath, SAMPLE_PDF_FILENAME);  { Внутренний доступ}
  Label1.Text:=PDFFileName;


	if (FindFirst(TPath.GetSharedDownloadsPath+'/*.pdf', faAnyFile, sr) = 0) then
	begin
		Memo1.Lines.Add(sr.Name);

	  while (FindNext(sr) = 0) do
		 begin
			Memo1.Lines.Add(sr.Name);
		 end;
	end;
	FindClose(sr);


  Uri := StrToJURI(PDFFileName);
  // Формируем намерение об открытии файла в стандартном приложении
  OpenLinkIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, Uri);
  // Устанавливаем тип данных
  OpenLinkIntent.setType(StringToJString('application/pdf'));
  OpenLinkIntent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_CLEAR_TOP);
  // Запускаем приложение и передаем ему наше намерение
  try
    SharedActivity.startActivity(OpenLinkIntent);
  except on E: Exception do
    ShowMessage('Не удалось открыть PDF. В системе нет доступных приложения для просмотра pdf');
  end;
end;

Что у меня не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
Цитата

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

Вот! Как раз этого у меня и нет. У меня несколько приложений и когда я пытаюсь открыть файл из диспетчера - вопрос о программе задается.

А в мой программе - нет. Пишет - не удалось открыть файл.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Похожий контент

    • От R.is
      Добрый день господа!
      Искал на форуме, но ответа не нашел. Кто нибудь открывал локальный pdf  webbrowser-ом?
      В Deployment есть два файла: '1.pdf' и '2.html', расположение assets\internal
      F1, F2: string; begin F2 := TPath.Combine(TPath.GetDocumentsPath, '1.pdf'); WebBrowser1.Url := ('file://' + F2); end; begin F1 := TPath.Combine(TPath.GetDocumentsPath, '2.html'); WebBrowser1.Url := ('file://' + F1); end; HTML страница загружается без проблем а вот pdf не загружается, в чем может быть проблема? 
      При открытии intent-ом предлагает выбрать читалку для открытия, что не очень красиво.
      Кто чем пользуется/открывает pdf?
    • От x11
      Хочу взять пример из этой темы:
      http://fire-monkey.ru/topic/1263-%D0%BE%D1%82%D0%BA%D1%80%D1%8B%D1%82%D0%B8%D0%B5-%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B8%D0%B7-image-%D0%B2-%D0%B3%D0%B0%D0%BB%D0%B5%D1%80%D0%B5%D0%B5/
      Но среда ругается на JIntent.
      Нажимаю Ctrl+Shift+A - пустота.
      Нажимаю F1 на Jintent - справка ничего не выдает.
      Смотрю пример из справки
      http://docwiki.embarcadero.com/CodeExamples/Berlin/en/FMX.Android_Intents_Sample
      Там тоже нет информации, что нужно подключить в USES.
      Ок, открыл сам пример из папки "C:\Users\Public\Documents\Embarcadero\Studio\18.0\Samples\Object Pascal\Mobile Snippets\AndroidIntents\ReceiveIntent"
      Среда подсказывает, что JInten живет в Androidapi.JNI.GraphicsContentViewText.
      Добавляю в свой модуль в USES Androidapi.JNI.GraphicsContentViewText, но мне среда выдает ошибку "Can not resolve Androidapi.JNI.GraphicsContentViewText"
    • От umkes
      Всем привет. Подскажите пожалуйста, чем можно отобразить PDF документ в программе? Это будет виндовс аппликация, в которой нужно будет открывать Pdf файлы.
    • От walexw
      Есть ли возможность при помощи FireMonkey-приложения, на андроид-устройстве, создать PDF-файл?
      (RAD Studio 10 Seattle)
      Спасибо.
    • От Features
      Задача чем-то похожа на http://fire-monkey.ru/topic/1291-ios-otkrytie-faila-iz-vashego-prilozheniia-v-drugom-p/ , но еще необходимо получить результат обработки обратно в свое приложение.
    • От Tovenar
      Как правильно отправлять файлы через ACTION_SEND. То что пробовал и не смог заставить работать:
      uses System.IOUtils, FMX.Helpers.Android,Androidapi.JNI.JavaTypes, Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText;     procedure TMain.SendFileClick(Sender: TObject);     var       Intent: JIntent;     begin       Intent := TJIntent.Create;       Intent.setAction(TJIntent.JavaClass.ACTION_SEND);       Intent.setDataAndType(StrToJURI('file:' + TPath.Combine(TPath.GetSharedDownloadsPath, 'picture.png')), StringToJString ('image/png'));       SharedActivity.startActivity(Intent);     end; или
      var Intent: JIntent; begin Intent := TJIntent.Create; Intent.setAction(TJIntent.JavaClass.ACTION_SEND); Intent.setType(StringToJString('image/png')); Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM , StringToJString('file:mnt/sdcard/pictures/1.png')); SharedActivity.startActivity(Intent); При чем с открытием(ACTION_VIEW) все в порядке:
      var   FileName, ExtFile: string;   mime: JMimeTypeMap;   ExtToMime: JString;   Intent: JIntent;   pathN:string; begin     FileName := Item.ItemData.Detail;     try       ExtFile := AnsiLowerCase(StringReplace(TPath.GetExtension(FileName), '.', '',[]));       mime := TJMimeTypeMap.JavaClass.getSingleton();       ExtToMime := mime.getMimeTypeFromExtension(StringToJString(ExtFile));       Intent := TJIntent.Create;       Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);       Intent.setDataAndType(StrToJURI('file:' + FileName), ExtToMime);       SharedActivity.startActivity(Intent);     except       ShowMessage('Невозможно открыть файл!');     end end; Хоть в моих примерах я и пытаюсь передать изображение (я в курсе, что в ActionList есть стандартное действие для отправки изображений), в итоге код будет использоваться для файлов любого типа. 
      Как победить?
    • От abwabw
      Хочу попробовать прикрутить к проекту для дроида googl-овское распознавание голоса. Нашёл пример реализации этой функции вот тут или тут.
      Помогите перевести на XE5 FM, вот этот кусок:
      package com.genisoft.inforino; import java.util.List; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.speech.RecognizerIntent; public class SpeechRecognitionHelper {     public static void run(Activity ownerActivity) {             startRecognitionActivity(ownerActivity);         }                 } private static void startRecognitionActivity(Activity ownerActivity) {      Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Голосовой поиск Inforino"); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);     intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "ru-RU"); ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);     }
    • От estra
      Можно ли средствами FM создать (в частности на Android) PDF файл?
    • От Kitty
      На планшете c Андроид 4.4.2 установлены root права. Из андроид маркета установлен MX плеер. В плеере установлена настройка, что он открывает на постоянной основе файлы mp4. Я пытаюсь из своей программы запустить на выполнение файл mp4. Для примера помещаю нужный мне файл mp4 в папку download. Код такой:
      //C++ Builder XE6 String VideoFileName = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetSharedDownloadsPath(), "file1.mp4"); if(FileExists(VideoFileName)) { system(("open " + AnsiString(VideoFileName)).c_str());//ничего не происходит ShowMessage(VideoFileName);// /mnt/internal_sd/Download/file1.mp4 } else { //сюда не попадаем ShowMessage(L"Не найден видео файл " + VideoFileName + L". Программа будет закрыта."); Application->Terminate(); } Ничего не происходит. Видео не воспроизводится. Как правильно?
    • От Brovin Yaroslav
      Чтобы добавить любое изображение в системную галерею изображений Андроида нужно:
      Получить универсальный URI к вашей картинке GetImageUri. Для этого сохраняем изображение (если изображение находится в памяти устройства, а не в файловой системе) в кэш приложения. Формируем намерение JIntent, что хотим добавить изображение. Задаем URI к картинке и делаем широковещательный запрос на все приложения, которые могут обработать наш запрос. // Сохранение изображения в кэш приложения и извлечение Url к этому файлу function GetImageUri(ABitmap: TBitmap): Jnet_Uri; var ImageFile: JFile; ImageUri: Jnet_Uri; FileNameTemp: JString; FileNameExt: JString; begin FileNameTemp := StringToJString('temp'); FileNameExt := StringToJString('.jpg'); try ImageFile := TJFile.JavaClass.createTempFile(FileNameTemp, FileNameExt); ImageUri := TJnet_Uri.JavaClass.fromFile(ImageFile); ABitmap.SaveToFile(JStringToString(ImageFile.getAbsolutePath)); finally Result := ImageUri; end; end; procedure AddPhotoToGallery(const APhoto: TBitmap); var Intent: JIntent; begin Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_MEDIA_SCANNER_SCAN_FILE); Intent.setData(GetImageUri(APhoto)); SharedActivity.sendBroadcast(Intent); end;
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...