Externí prohlížeč PDF ve Firemonkey pro Windows a Android

vložil Radek Červinka 20. ledna 2023 21:32

Znělo to jednoduše: mám napsaný další program pro Android a zákazník si přál mít ještě možnost stáhnout a spustit PDF v externím prohlížeči.

Všechny aplikace pro Android ladím jako Win32 aplikace s pár IFDEF a pak to jen přeložím pro Android a upravím sem tam design a pár speciálních funkcí, velmi výrazně to zrychluje vývoj. A tak jsem na to šel i při zobrazení PDF.

A jako bonus se zmíníme o AndroidManifest.xml a AndroidManifest.template.xml .

Stáhnutí PDF bylo pár řádků díky THTTPClient a pro zobrazení na windows z VCL jsem věděl, že nejjednodušší je ShellExecute.

Napíši nejprve finální stav (jako metodu formuláře) a pak si k tomu něco řekneme, ať se taky zasmějete.

uses
….
  Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Net
…

procedure TForm1.mStartPdf(const sFile: string);
{$IFDEF ANDROID}
 var
  Intent: JIntent;
  LUri: Jnet_Uri;
{$ENDIF}
begin
{$IFDEF ANDROID}
  LUri := TAndroidHelper.JFileToJURI(TJFile.JavaClass.init(StringToJString(sFile)));

  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW);
  intent.setDataAndType(LUri, StringToJstring('application/pdf'));
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NO_HISTORY or
     TJIntent.JavaClass.FLAG_ACTIVITY_CLEAR_TOP or
     TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);

  TAndroidHelper.Activity.startActivity(Intent);
{$ELSE}
  if IsDebuggerPresent then
    ShowMessage('Running under debugger:'+sFile)
  else
    ShellExecute(0{WindowHandleToPlatform(Handle).Wnd}, nil, PChar(sFile), nil, nil, SW_SHOW);
{$ENDIF}
end;

Pro Android ještě v Project Options - Application - User Permission zkontrolujte práva, nemělo by tam být třeba nic speciálního, ale v Entitlement List zkontrolujte Secure File Sharing. Pokud tam tuto volbu nemáte, máte staré delphi a musíte si pomoci manuálně třeba Opening a PDF on Android with Delphi.

Secure File Sharing

No těchto pár řádků mne stálo přes několik hodin převážně Androidího pekla. Ale nejprve windows, tam je to skoro normální ShellExecute, až na to, že autor těchto řádků zapomněl, že Acrobat Reader se nemá rád s debuggerem a většinou vytuhne, pokud se spustí z IDE. Mea culpa. To bylo první tlučení hlavou o stůl.

Aplikace pod windows fungovala ok, přeložil jsem pod Android, upravil pár cest za pomoci System.IOUtils.TPath.GetPublicPath nebo podobné (připomínám, že System.IOUtils.TPath.Combine(System.IOUtils.TPath.GetPublicPath, 'demo.pdf') je bezpečné, zapomeňte na / místo toho PathDelim nebo funkce), a jal se hledat jak spustit pdf.

Dělá se to přes Intent, s tím souhlasí všichni (myslím v různých jazycích). Nejenže se to liší dle verze androidu (krásně to odstiňuje Delphi funkce TAndroidHelper.JFileToJURI, takže nemusíte řešit opičky s FileProvider od jisté verze Androidu), ale např. nastavení flagů se liší dle verze taky. Navíc někdo doporučuje ACTION_VIEW, někdo něco jiného atd. Někdo pro změnu preferuje to zobrazit v prohlížeči internetu.

No nebudu to napínat, výsledek je nahoře. Uvedený kód by mohl fungovat i pro jiné dokumenty, jen ten typ se liší (existuje na to API).

AndroidManifest.xml

Uvedený soubor je soubor Androidu, který je součástí každé apk a dá se tím specifikovat chování. Delphi to převážně obsluhují sami, ale dá se to měnit. V adresáři projektu je AndroidManifest.template.xml, ze kterého je daný soubor vytvářen. Jedná se o XML (v obou případech), vysledný AndroidManifest.xml je pak v adresáři debug nebo release. Uvedená volba na screenshotu způsobí, že do manifestu jsou přigenerovány "providery", tj. cesty, která pak jsou známy.

Důležité: template pro AndroidManifest.template.xml (tj. šablona pro šablonu) je v adresáři c:\Users\{user}\AppData\Roaming\Embarcadero\BDS\22.0\ a při aktualizacích si nejsem jistý zda se maže. Důležité je, že pokud si ho poškodíte, tak ho normálně smažte a IDE ho při startu vygeneruje znovu.

Zajímavé kódy pro PDF, Android a Delphi

github.com/AlessandroMartini/Delphi-Android-GeraPDF - generování a zobrazení PDF na Androidu, nutno upravit to zobrazení (to je jedna z variant co dříve fungovala), ale generování je OK

github.com/DelphiWorlds/Kastri/tree/master/Features/AndroidPDF - control na zobrazování PDF na Androidu

No dnes to bylo takové jednostranné, ale myslím, že to někomu v budoucnosti pomůže. A určitě mi v komentářích napíšete, že to jde řešit mnohem jednodušeji, já jsem to pro aktuální android lépe nedokázal.

Tagy: , ,

FireMonkey

Komentáře

21.1.2023 14:34:27 #

Daniel_Andrascik

Android vie riadne vytrapit niekedy. Inak Acrobat reader mi nesmie do baraku. Uz asi 20 rokov pouzivam Foxit reader na vsetkych PC ktore spravujem. Pred 20timi rokmi ked som studoval datasheety ku roznym zariadeniam s mnozstvom technickych nakresov (obrazky) tak mi Acrobat reader velmi lagoval. Foxit reader bol minimalne 5x sviznejsi. Odvtedy som Acrobat reader nenainstaloval. Ci je dnes situacia lepsia to uz netusim.

Daniel_Andrascik

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců