├── .gitattributes ├── .gitignore ├── README.md ├── Samples ├── AndroidManifest.template.xml ├── DelphiExternalFileViewerSample.deployproj ├── DelphiExternalFileViewerSample.dpr ├── DelphiExternalFileViewerSample.dproj ├── Entitlement.TemplateiOS.xml ├── FForm.fmx ├── FForm.pas ├── info.plist.TemplateiOS.xml └── svn-book.pdf └── Source ├── Android ├── Androidapi.JNI.Environment.pas └── UExternalFileViewer.Android.pas ├── UExternalFileViewer.pas ├── UOpenURLUtils.pas └── iOS └── UExternalFileViewer.iOS.pas /.gitattributes: -------------------------------------------------------------------------------- 1 | # Don't let git change default linebreaks 2 | *.xml text eol=lf 3 | .gitattributes text eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.local 2 | *.res 3 | *.stat 4 | *.identcache 5 | *.hpp 6 | 7 | Debug/ 8 | Release/ 9 | 10 | __history/ 11 | __recovery/ 12 | __astcache/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # firemonkey-external-file-viewer 2 | Delphi utility class for opening various files in external apps from Firemonkey application on Android and iOS 3 | 4 | For more details, see the accompanying blog post at https://www.code-partners.com/open-files-in-external-apps-from-firemonkey/ 5 | -------------------------------------------------------------------------------- /Samples/AndroidManifest.template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | <%uses-permission%> 12 | 13 | 21 | 22 | <%application-meta-data%> 23 | <%services%> 24 | 26 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | <%activity%> 39 | <%receivers%> 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Samples/DelphiExternalFileViewerSample.deployproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 12 5 | 6 | 7 | ad051703c071eb11e2 8 | 03710820612b5ae95f0699fa6cdd35b5658bc656 9 | dc398986acabb53bce25b5f6a2661fdbf3da125b 10 | 71CF41E2-0AEC-4D5A-9E91-6F3BA4593339 11 | 12 | 13 | 14 | DelphiExternalFileViewerSample.app\ 15 | Default-568h@2x.png 16 | iPhone_Launch640x1136 17 | 1 18 | 19 | 20 | True 21 | 22 | 23 | DelphiExternalFileViewerSample.app\ 24 | FM_ApplicationIcon_180x180.png 25 | iPhone_AppIcon180 26 | 0 27 | 28 | 29 | True 30 | 31 | 32 | DelphiExternalFileViewerSample.app\ 33 | FM_ApplicationIcon_57x57.png 34 | iPhone_AppIcon57 35 | 0 36 | 37 | 38 | True 39 | 40 | 41 | DelphiExternalFileViewerSample.app\ 42 | FM_ApplicationIcon_144x144.png 43 | iPad_AppIcon144 44 | 0 45 | 46 | 47 | True 48 | 49 | 50 | DelphiExternalFileViewerSample.app\ 51 | FM_ApplicationIcon_60x60.png 52 | iPhone_AppIcon60 53 | 0 54 | 55 | 56 | True 57 | 58 | 59 | DelphiExternalFileViewerSample.app\ 60 | Default-667h@2x.png 61 | iPhone_Launch750 62 | 0 63 | 64 | 65 | True 66 | 67 | 68 | DelphiExternalFileViewerSample.app\ 69 | FM_SettingIcon_29x29.png 70 | iPad_Setting29 71 | 0 72 | 73 | 74 | True 75 | 76 | 77 | DelphiExternalFileViewerSample.app\..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF\ 78 | DelphiExternalFileViewerSample 79 | ProjectiOSDeviceDebug 80 | 1 81 | 82 | 83 | True 84 | 85 | 86 | DelphiExternalFileViewerSample.app\ 87 | Default@2x.png 88 | iPhone_Launch640 89 | 1 90 | 91 | 92 | True 93 | 94 | 95 | DelphiExternalFileViewerSample.app\StartUp\Documents\ 96 | svn-book.pdf 97 | File 98 | 0 99 | 100 | 101 | True 102 | 103 | 104 | DelphiExternalFileViewerSample.app\ 105 | FM_SettingIcon_58x58.png 106 | iPad_Setting58 107 | 0 108 | 109 | 110 | True 111 | 112 | 113 | DelphiExternalFileViewerSample.app\ 114 | Default.png 115 | iPhone_Launch320 116 | 1 117 | 118 | 119 | True 120 | 121 | 122 | DelphiExternalFileViewerSample.app\ 123 | Default-Portrait@2x.png 124 | iPad_Launch1536 125 | 1 126 | 127 | 128 | True 129 | 130 | 131 | DelphiExternalFileViewerSample.app\ 132 | FM_ApplicationIcon_72x72.png 133 | iPad_AppIcon72 134 | 0 135 | 136 | 137 | True 138 | 139 | 140 | DelphiExternalFileViewerSample.app\ 141 | Default-Landscape@2x.png 142 | iPad_Launch2048 143 | 1 144 | 145 | 146 | True 147 | 148 | 149 | DelphiExternalFileViewerSample.app\ 150 | FM_ApplicationIcon_120x120.png 151 | iPhone_AppIcon120 152 | 0 153 | 154 | 155 | True 156 | 157 | 158 | DelphiExternalFileViewerSample.app\ 159 | Default-Portrait@2x~ipad.png 160 | iPad_Launch1536x2048 161 | 0 162 | 163 | 164 | True 165 | 166 | 167 | DelphiExternalFileViewerSample.app\ 168 | FM_SpotlightSearchIcon_100x100.png 169 | iPad_SpotLight100 170 | 0 171 | 172 | 173 | True 174 | 175 | 176 | DelphiExternalFileViewerSample.app\ 177 | FM_SpotlightSearchIcon_58x58.png 178 | iPhone_Spotlight58 179 | 0 180 | 181 | 182 | True 183 | 184 | 185 | DelphiExternalFileViewerSample.app\..\ 186 | DelphiExternalFileViewerSample.entitlements 187 | ProjectiOSEntitlements 188 | 1 189 | 190 | 191 | True 192 | 193 | 194 | DelphiExternalFileViewerSample.app\ 195 | Default~ipad.png 196 | iPad_Launch768 197 | 1 198 | 199 | 200 | True 201 | 202 | 203 | DelphiExternalFileViewerSample.app\ 204 | Default-Landscape-812h@3x.png 205 | iPhone_Launch2436 206 | 0 207 | 208 | 209 | True 210 | 211 | 212 | DelphiExternalFileViewerSample.app\ 213 | Default-Portrait~ipad.png 214 | iPad_Launch768x1024 215 | 0 216 | 217 | 218 | True 219 | 220 | 221 | DelphiExternalFileViewerSample.app\ 222 | FM_ApplicationIcon_114x114.png 223 | iPhone_AppIcon114 224 | 0 225 | 226 | 227 | True 228 | 229 | 230 | DelphiExternalFileViewerSample.app\ 231 | FM_SpotlightSearchIcon_50x50.png 232 | iPad_SpotLight50 233 | 0 234 | 235 | 236 | True 237 | 238 | 239 | DelphiExternalFileViewerSample.app\ 240 | FM_ApplicationIcon_76x76.png 241 | iPad_AppIcon76 242 | 0 243 | 244 | 245 | True 246 | 247 | 248 | DelphiExternalFileViewerSample.app\ 249 | FM_SpotlightSearchIcon_80x80.png 250 | iPhone_Spotlight80 251 | 0 252 | 253 | 254 | True 255 | 256 | 257 | DelphiExternalFileViewerSample.app\ 258 | FM_SpotlightSearchIcon_80x80.png 259 | iPad_SpotLight80 260 | 0 261 | 262 | 263 | True 264 | 265 | 266 | DelphiExternalFileViewerSample.app\ 267 | Default-Landscape-736h@3x.png 268 | iPhone_Launch2208 269 | 0 270 | 271 | 272 | True 273 | 274 | 275 | DelphiExternalFileViewerSample.app\ 276 | FM_SpotlightSearchIcon_40x40.png 277 | iPhone_Spotlight40 278 | 0 279 | 280 | 281 | True 282 | 283 | 284 | DelphiExternalFileViewerSample.app\ 285 | Default-736h@3x.png 286 | iPhone_Launch1242 287 | 0 288 | 289 | 290 | True 291 | 292 | 293 | DelphiExternalFileViewerSample.app\ 294 | Info.plist 295 | ProjectiOSInfoPList 296 | 1 297 | 298 | 299 | True 300 | 301 | 302 | DelphiExternalFileViewerSample.app\StartUp\Documents\ 303 | svn-book.pdf 304 | File 305 | 0 306 | 307 | 308 | True 309 | 310 | 311 | DelphiExternalFileViewerSample.app\ 312 | Default-812h@3x.png 313 | iPhone_Launch1125 314 | 0 315 | 316 | 317 | True 318 | 319 | 320 | DelphiExternalFileViewerSample.app\ 321 | DelphiExternalFileViewerSample 322 | ProjectOutput 323 | 1 324 | 325 | 326 | True 327 | True 328 | 329 | 330 | DelphiExternalFileViewerSample.app\ 331 | Default-Landscape.png 332 | iPad_Launch1024 333 | 1 334 | 335 | 336 | True 337 | 338 | 339 | DelphiExternalFileViewerSample.app\ 340 | FM_ApplicationIcon_152x152.png 341 | iPad_AppIcon152 342 | 0 343 | 344 | 345 | True 346 | 347 | 348 | DelphiExternalFileViewerSample.app\ 349 | FM_SpotlightSearchIcon_40x40.png 350 | iPad_SpotLight40 351 | 0 352 | 353 | 354 | True 355 | 356 | 357 | DelphiExternalFileViewerSample.app\ 358 | FM_ApplicationIcon_87x87.png 359 | iPhone_AppIcon87 360 | 0 361 | 362 | 363 | True 364 | 365 | 366 | DelphiExternalFileViewerSample.app\ 367 | FM_SpotlightSearchIcon_29x29.png 368 | iPhone_Spotlight29 369 | 0 370 | 371 | 372 | True 373 | 374 | 375 | DelphiExternalFileViewerSample.app\ 376 | ResourceRules.plist 377 | ProjectiOSDeviceResourceRules 378 | 1 379 | 380 | 381 | True 382 | 383 | 384 | DelphiExternalFileViewerSample.app\ 385 | Default-Landscape@2x~ipad.png 386 | iPad_Launch2048x1536 387 | 0 388 | 389 | 390 | True 391 | 392 | 393 | DelphiExternalFileViewerSample.app\ 394 | Default-Landscape~ipad.png 395 | iPad_Launch1024x768 396 | 0 397 | 398 | 399 | True 400 | 401 | 402 | 403 | 404 | 405 | DelphiExternalFileViewerSample.app\StartUp\Documents\ 406 | svn-book.pdf 407 | File 408 | 0 409 | 410 | 411 | True 412 | 413 | 414 | DelphiExternalFileViewerSample.app\StartUp\Documents\ 415 | svn-book.pdf 416 | File 417 | 0 418 | 419 | 420 | True 421 | 422 | 423 | 424 | 425 | DelphiExternalFileViewerSample\ 426 | DelphiExternalFileViewerSample.exe 427 | ProjectOutput 428 | 0 429 | 430 | 431 | True 432 | True 433 | 434 | 435 | 436 | 437 | 438 | DelphiExternalFileViewerSample.app\Contents\MacOS\ 439 | libcgsqlite3.dylib 440 | DependencyModule 441 | 1 442 | 443 | 444 | True 445 | 446 | 447 | DelphiExternalFileViewerSample.app\Contents\MacOS\ 448 | libcgunwind.1.0.dylib 449 | DependencyModule 450 | 1 451 | 452 | 453 | True 454 | 455 | 456 | 457 | 458 | DelphiExternalFileViewerSample\res\drawable-ldpi\ 459 | ic_launcher.png 460 | Android_LauncherIcon36 461 | 1 462 | 463 | 464 | True 465 | 466 | 467 | DelphiExternalFileViewerSample\res\drawable-hdpi\ 468 | ic_launcher.png 469 | Android_LauncherIcon72 470 | 1 471 | 472 | 473 | True 474 | 475 | 476 | DelphiExternalFileViewerSample\res\drawable-small\ 477 | splash_image.png 478 | Android_SplashImage426 479 | 1 480 | 481 | 482 | True 483 | 484 | 485 | DelphiExternalFileViewerSample\assets\internal\ 486 | svn-book.pdf 487 | File 488 | 0 489 | 490 | 491 | True 492 | 493 | 494 | DelphiExternalFileViewerSample\library\lib\mips\ 495 | libDelphiExternalFileViewerSample.so 496 | AndroidLibnativeMipsFile 497 | 1 498 | 499 | 500 | True 501 | 502 | 503 | DelphiExternalFileViewerSample\res\drawable\ 504 | splash_image_def.xml 505 | AndroidSplashImageDef 506 | 1 507 | 508 | 509 | True 510 | 511 | 512 | DelphiExternalFileViewerSample\ 513 | AndroidManifest.xml 514 | ProjectAndroidManifest 515 | 1 516 | 517 | 518 | True 519 | 520 | 521 | DelphiExternalFileViewerSample\library\lib\armeabi\ 522 | libDelphiExternalFileViewerSample.so 523 | AndroidLibnativeArmeabiFile 524 | 1 525 | 526 | 527 | True 528 | 529 | 530 | DelphiExternalFileViewerSample\res\drawable-xxhdpi\ 531 | ic_launcher.png 532 | Android_LauncherIcon144 533 | 1 534 | 535 | 536 | True 537 | 538 | 539 | DelphiExternalFileViewerSample\res\drawable-xhdpi\ 540 | ic_launcher.png 541 | Android_LauncherIcon96 542 | 1 543 | 544 | 545 | True 546 | 547 | 548 | DelphiExternalFileViewerSample\assets\internal\ 549 | svn-book.pdf 550 | File 551 | 0 552 | 553 | 554 | True 555 | 556 | 557 | DelphiExternalFileViewerSample\res\drawable-large\ 558 | splash_image.png 559 | Android_SplashImage640 560 | 1 561 | 562 | 563 | True 564 | 565 | 566 | DelphiExternalFileViewerSample\res\drawable-xlarge\ 567 | splash_image.png 568 | Android_SplashImage960 569 | 1 570 | 571 | 572 | True 573 | 574 | 575 | DelphiExternalFileViewerSample\res\drawable-mdpi\ 576 | ic_launcher.png 577 | Android_LauncherIcon48 578 | 1 579 | 580 | 581 | True 582 | 583 | 584 | DelphiExternalFileViewerSample\classes\ 585 | classes.dex 586 | AndroidClassesDexFile 587 | 1 588 | 589 | 590 | True 591 | 592 | 593 | DelphiExternalFileViewerSample\library\lib\armeabi-v7a\ 594 | gdbserver 595 | AndroidGDBServer 596 | 1 597 | 598 | 599 | True 600 | 601 | 602 | DelphiExternalFileViewerSample\res\values\ 603 | styles.xml 604 | AndroidSplashStyles 605 | 1 606 | 607 | 608 | True 609 | 610 | 611 | DelphiExternalFileViewerSample\library\lib\armeabi-v7a\ 612 | libDelphiExternalFileViewerSample.so 613 | ProjectOutput 614 | 1 615 | 616 | 617 | True 618 | True 619 | 620 | 621 | DelphiExternalFileViewerSample\res\drawable-normal\ 622 | splash_image.png 623 | Android_SplashImage470 624 | 1 625 | 626 | 627 | True 628 | 629 | 630 | 631 | 632 | DelphiExternalFileViewerSample.app\ 633 | libcgunwind.1.0.dylib 634 | DependencyModule 635 | 1 636 | 637 | 638 | True 639 | 640 | 641 | DelphiExternalFileViewerSample.app\StartUp\Documents\ 642 | svn-book.pdf 643 | File 644 | 0 645 | 646 | 647 | True 648 | 649 | 650 | DelphiExternalFileViewerSample.app\StartUp\Documents\ 651 | svn-book.pdf 652 | File 653 | 0 654 | 655 | 656 | True 657 | 658 | 659 | DelphiExternalFileViewerSample.app\ 660 | libPCRE.dylib 661 | DependencyModule 662 | 1 663 | 664 | 665 | True 666 | 667 | 668 | 669 | -------------------------------------------------------------------------------- /Samples/DelphiExternalFileViewerSample.dpr: -------------------------------------------------------------------------------- 1 | program DelphiExternalFileViewerSample; 2 | 3 | uses 4 | System.StartUpCopy, 5 | FMX.Forms, 6 | FForm in 'FForm.pas' {Form5}, 7 | UExternalFileViewer in '..\Source\UExternalFileViewer.pas', 8 | Androidapi.JNI.Environment in '..\Source\Android\Androidapi.JNI.Environment.pas', 9 | UExternalFileViewer.Android in '..\Source\Android\UExternalFileViewer.Android.pas', 10 | UOpenURLUtils in '..\Source\UOpenURLUtils.pas', 11 | UExternalFileViewer.iOS in '..\Source\iOS\UExternalFileViewer.iOS.pas'; 12 | 13 | {$R *.res} 14 | 15 | begin 16 | Application.Initialize; 17 | Application.CreateForm(TForm5, Form5); 18 | Application.Run; 19 | end. 20 | -------------------------------------------------------------------------------- /Samples/DelphiExternalFileViewerSample.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {C303F817-7BE1-461E-9D04-38ACC69A1942} 4 | 18.3 5 | FMX 6 | DelphiExternalFileViewerSample.dpr 7 | True 8 | Debug 9 | Win32 10 | 1119 11 | Application 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Base 29 | true 30 | 31 | 32 | true 33 | Base 34 | true 35 | 36 | 37 | true 38 | Base 39 | true 40 | 41 | 42 | true 43 | Base 44 | true 45 | 46 | 47 | true 48 | Base 49 | true 50 | 51 | 52 | true 53 | Base 54 | true 55 | 56 | 57 | true 58 | Cfg_1 59 | true 60 | true 61 | 62 | 63 | true 64 | Cfg_1 65 | true 66 | true 67 | 68 | 69 | true 70 | Base 71 | true 72 | 73 | 74 | true 75 | Cfg_2 76 | true 77 | true 78 | 79 | 80 | true 81 | Cfg_2 82 | true 83 | true 84 | 85 | 86 | .\$(Platform)\$(Config) 87 | .\$(Platform)\$(Config) 88 | false 89 | false 90 | false 91 | false 92 | false 93 | RESTComponents;emsclientfiredac;DataSnapFireDAC;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FireDACSqliteDriver;soaprtl;soapmidas;$(DCC_UsePackage) 94 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 95 | true 96 | true 97 | true 98 | true 99 | true 100 | true 101 | true 102 | true 103 | true 104 | true 105 | $(BDS)\bin\delphi_PROJECTICON.ico 106 | $(BDS)\bin\delphi_PROJECTICNS.icns 107 | DelphiExternalFileViewerSample 108 | 109 | 110 | DBXSqliteDriver;DBXInterBaseDriver;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) 111 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= 112 | Debug 113 | true 114 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png 115 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png 116 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png 117 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png 118 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png 119 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png 120 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png 121 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png 122 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png 123 | android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar 124 | 125 | 126 | DBXSqliteDriver;DBXInterBaseDriver;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage) 127 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera 128 | iPhoneAndiPad 129 | true 130 | Debug 131 | $(MSBuildProjectName) 132 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png 133 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png 134 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png 135 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png 136 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 137 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png 138 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png 139 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png 140 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png 141 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png 142 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png 143 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png 144 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png 145 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png 146 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png 147 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png 148 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png 149 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 150 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png 151 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png 152 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png 153 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 154 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png 155 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png 156 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png 157 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png 158 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png 159 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png 160 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png 161 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png 162 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png 163 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png 164 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 165 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png 166 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png 167 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png 168 | 169 | 170 | DBXSqliteDriver;DBXInterBaseDriver;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;TMSFMXPackPkgDXE11;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage) 171 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera 172 | iPhoneAndiPad 173 | true 174 | Debug 175 | $(MSBuildProjectName) 176 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png 177 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png 178 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png 179 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png 180 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 181 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png 182 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png 183 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png 184 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png 185 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png 186 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png 187 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png 188 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png 189 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png 190 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png 191 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png 192 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png 193 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 194 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png 195 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png 196 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png 197 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 198 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png 199 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png 200 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png 201 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png 202 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png 203 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png 204 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png 205 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png 206 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png 207 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png 208 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 209 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png 210 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png 211 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png 212 | 213 | 214 | DBXSqliteDriver;DBXInterBaseDriver;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage) 215 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera 216 | iPhoneAndiPad 217 | true 218 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png 219 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png 220 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png 221 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png 222 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 223 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png 224 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png 225 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png 226 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png 227 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png 228 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png 229 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png 230 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png 231 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png 232 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png 233 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png 234 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png 235 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 236 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png 237 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png 238 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png 239 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 240 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png 241 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png 242 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png 243 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png 244 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png 245 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png 246 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png 247 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png 248 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png 249 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png 250 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 251 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png 252 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png 253 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png 254 | 255 | 256 | DBXSqliteDriver;DataSnapServerMidas;DBXInterBaseDriver;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) 257 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts 258 | Debug 259 | true 260 | 261 | 262 | DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;TMSFMXPackPkgDXE11;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) 263 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 264 | Debug 265 | true 266 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 267 | 1033 268 | $(BDS)\bin\default_app.manifest 269 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png 270 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png 271 | 272 | 273 | DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) 274 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) 275 | Debug 276 | true 277 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 278 | 1033 279 | $(BDS)\bin\default_app.manifest 280 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png 281 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png 282 | 283 | 284 | DEBUG;$(DCC_Define) 285 | true 286 | false 287 | true 288 | true 289 | true 290 | 291 | 292 | false 293 | true 294 | true 295 | 296 | 297 | true 298 | true 299 | 300 | 301 | false 302 | RELEASE;$(DCC_Define) 303 | 0 304 | 0 305 | 306 | 307 | true 308 | true 309 | 310 | 311 | true 312 | true 313 | 314 | 315 | 316 | MainSource 317 | 318 | 319 |
Form5
320 | fmx 321 |
322 | 323 | 324 | 325 | 326 | 327 | 328 | Cfg_2 329 | Base 330 | 331 | 332 | Base 333 | 334 | 335 | Cfg_1 336 | Base 337 | 338 |
339 | 340 | Delphi.Personality.12 341 | Application 342 | 343 | 344 | 345 | DelphiExternalFileViewerSample.dpr 346 | 347 | 348 | 349 | 350 | 351 | ic_launcher.png 352 | true 353 | 354 | 355 | 356 | 357 | ic_launcher.png 358 | true 359 | 360 | 361 | 362 | 363 | Default-568h@2x.png 364 | true 365 | 366 | 367 | 368 | 369 | true 370 | 371 | 372 | 373 | 374 | true 375 | 376 | 377 | 378 | 379 | true 380 | 381 | 382 | 383 | 384 | splash_image.png 385 | true 386 | 387 | 388 | 389 | 390 | .\assets\internal\ 391 | svn-book.pdf 392 | true 393 | 394 | 395 | 396 | 397 | true 398 | 399 | 400 | 401 | 402 | Default-667h@2x.png 403 | true 404 | 405 | 406 | 407 | 408 | libDelphiExternalFileViewerSample.so 409 | true 410 | 411 | 412 | 413 | 414 | true 415 | 416 | 417 | 418 | 419 | DelphiExternalFileViewerSample 420 | true 421 | 422 | 423 | 424 | 425 | true 426 | 427 | 428 | 429 | 430 | Default@2x.png 431 | true 432 | 433 | 434 | 435 | 436 | StartUp\Documents\ 437 | svn-book.pdf 438 | true 439 | 440 | 441 | 442 | 443 | StartUp\Documents\ 444 | svn-book.pdf 445 | true 446 | 447 | 448 | 449 | 450 | true 451 | 452 | 453 | 454 | 455 | true 456 | 457 | 458 | 459 | 460 | libDelphiExternalFileViewerSample.so 461 | true 462 | 463 | 464 | 465 | 466 | ic_launcher.png 467 | true 468 | 469 | 470 | 471 | 472 | true 473 | 474 | 475 | 476 | 477 | StartUp\Documents\ 478 | svn-book.pdf 479 | true 480 | 481 | 482 | 483 | 484 | true 485 | 486 | 487 | 488 | 489 | Default.png 490 | true 491 | 492 | 493 | 494 | 495 | Default-Portrait@2x.png 496 | true 497 | 498 | 499 | 500 | 501 | true 502 | 503 | 504 | 505 | 506 | true 507 | 508 | 509 | 510 | 511 | ic_launcher.png 512 | true 513 | 514 | 515 | 516 | 517 | StartUp\Documents\ 518 | svn-book.pdf 519 | true 520 | 521 | 522 | 523 | 524 | Default-Landscape@2x.png 525 | true 526 | 527 | 528 | 529 | 530 | true 531 | 532 | 533 | 534 | 535 | Default-Portrait@2x~ipad.png 536 | true 537 | 538 | 539 | 540 | 541 | true 542 | 543 | 544 | 545 | 546 | true 547 | 548 | 549 | 550 | 551 | true 552 | 553 | 554 | 555 | 556 | Default~ipad.png 557 | true 558 | 559 | 560 | 561 | 562 | Default-Landscape-812h@3x.png 563 | true 564 | 565 | 566 | 567 | 568 | .\assets\internal\ 569 | svn-book.pdf 570 | true 571 | 572 | 573 | 574 | 575 | Default-Portrait~ipad.png 576 | true 577 | 578 | 579 | 580 | 581 | splash_image.png 582 | true 583 | 584 | 585 | 586 | 587 | splash_image.png 588 | true 589 | 590 | 591 | 592 | 593 | DelphiExternalFileViewerSample.exe 594 | true 595 | 596 | 597 | 598 | 599 | StartUp\Documents\ 600 | svn-book.pdf 601 | true 602 | 603 | 604 | 605 | 606 | true 607 | 608 | 609 | 610 | 611 | true 612 | 613 | 614 | 615 | 616 | true 617 | 618 | 619 | 620 | 621 | true 622 | 623 | 624 | 625 | 626 | true 627 | 628 | 629 | 630 | 631 | ic_launcher.png 632 | true 633 | 634 | 635 | 636 | 637 | true 638 | 639 | 640 | 641 | 642 | Default-Landscape-736h@3x.png 643 | true 644 | 645 | 646 | 647 | 648 | classes.dex 649 | true 650 | 651 | 652 | 653 | 654 | true 655 | 656 | 657 | 658 | 659 | true 660 | 661 | 662 | 663 | 664 | true 665 | 666 | 667 | 668 | 669 | Default-736h@3x.png 670 | true 671 | 672 | 673 | 674 | 675 | Info.plist 676 | true 677 | 678 | 679 | 680 | 681 | StartUp\Documents\ 682 | svn-book.pdf 683 | true 684 | 685 | 686 | 687 | 688 | libDelphiExternalFileViewerSample.so 689 | true 690 | 691 | 692 | 693 | 694 | splash_image.png 695 | true 696 | 697 | 698 | 699 | 700 | Default-812h@3x.png 701 | true 702 | 703 | 704 | 705 | 706 | DelphiExternalFileViewerSample 707 | true 708 | 709 | 710 | 711 | 712 | Default-Landscape.png 713 | true 714 | 715 | 716 | 717 | 718 | true 719 | 720 | 721 | 722 | 723 | true 724 | 725 | 726 | 727 | 728 | true 729 | 730 | 731 | 732 | 733 | true 734 | 735 | 736 | 737 | 738 | ResourceRules.plist 739 | true 740 | 741 | 742 | 743 | 744 | Default-Landscape@2x~ipad.png 745 | true 746 | 747 | 748 | 749 | 750 | Default-Landscape~ipad.png 751 | true 752 | 753 | 754 | 755 | 756 | 1 757 | 758 | 759 | Contents\MacOS 760 | 1 761 | 762 | 763 | Contents\MacOS 764 | 0 765 | 766 | 767 | 768 | 769 | classes 770 | 1 771 | 772 | 773 | 774 | 775 | library\lib\armeabi-v7a 776 | 1 777 | 778 | 779 | 780 | 781 | library\lib\armeabi 782 | 1 783 | 784 | 785 | 786 | 787 | library\lib\mips 788 | 1 789 | 790 | 791 | 792 | 793 | library\lib\armeabi-v7a 794 | 1 795 | 796 | 797 | 798 | 799 | res\drawable 800 | 1 801 | 802 | 803 | 804 | 805 | res\values 806 | 1 807 | 808 | 809 | 810 | 811 | res\drawable 812 | 1 813 | 814 | 815 | 816 | 817 | res\drawable-xxhdpi 818 | 1 819 | 820 | 821 | 822 | 823 | res\drawable-ldpi 824 | 1 825 | 826 | 827 | 828 | 829 | res\drawable-mdpi 830 | 1 831 | 832 | 833 | 834 | 835 | res\drawable-hdpi 836 | 1 837 | 838 | 839 | 840 | 841 | res\drawable-xhdpi 842 | 1 843 | 844 | 845 | 846 | 847 | res\drawable-small 848 | 1 849 | 850 | 851 | 852 | 853 | res\drawable-normal 854 | 1 855 | 856 | 857 | 858 | 859 | res\drawable-large 860 | 1 861 | 862 | 863 | 864 | 865 | res\drawable-xlarge 866 | 1 867 | 868 | 869 | 870 | 871 | 1 872 | 873 | 874 | Contents\MacOS 875 | 1 876 | 877 | 878 | 0 879 | 880 | 881 | 882 | 883 | Contents\MacOS 884 | 1 885 | .framework 886 | 887 | 888 | 0 889 | 890 | 891 | 892 | 893 | 1 894 | .dylib 895 | 896 | 897 | 1 898 | .dylib 899 | 900 | 901 | 1 902 | .dylib 903 | 904 | 905 | Contents\MacOS 906 | 1 907 | .dylib 908 | 909 | 910 | 0 911 | .dll;.bpl 912 | 913 | 914 | 915 | 916 | 1 917 | .dylib 918 | 919 | 920 | 1 921 | .dylib 922 | 923 | 924 | 1 925 | .dylib 926 | 927 | 928 | Contents\MacOS 929 | 1 930 | .dylib 931 | 932 | 933 | 0 934 | .bpl 935 | 936 | 937 | 938 | 939 | 0 940 | 941 | 942 | 0 943 | 944 | 945 | 0 946 | 947 | 948 | 0 949 | 950 | 951 | Contents\Resources\StartUp\ 952 | 0 953 | 954 | 955 | 0 956 | 957 | 958 | 959 | 960 | 1 961 | 962 | 963 | 1 964 | 965 | 966 | 1 967 | 968 | 969 | 970 | 971 | 1 972 | 973 | 974 | 1 975 | 976 | 977 | 1 978 | 979 | 980 | 981 | 982 | 1 983 | 984 | 985 | 1 986 | 987 | 988 | 1 989 | 990 | 991 | 992 | 993 | 1 994 | 995 | 996 | 1 997 | 998 | 999 | 1 1000 | 1001 | 1002 | 1003 | 1004 | 1 1005 | 1006 | 1007 | 1 1008 | 1009 | 1010 | 1 1011 | 1012 | 1013 | 1014 | 1015 | 1 1016 | 1017 | 1018 | 1 1019 | 1020 | 1021 | 1 1022 | 1023 | 1024 | 1025 | 1026 | 1 1027 | 1028 | 1029 | 1 1030 | 1031 | 1032 | 1 1033 | 1034 | 1035 | 1036 | 1037 | 1 1038 | 1039 | 1040 | 1041 | 1042 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1043 | 1 1044 | 1045 | 1046 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1047 | 1 1048 | 1049 | 1050 | 1051 | 1052 | 1 1053 | 1054 | 1055 | 1 1056 | 1057 | 1058 | 1059 | 1060 | ..\ 1061 | 1 1062 | 1063 | 1064 | ..\ 1065 | 1 1066 | 1067 | 1068 | 1069 | 1070 | 1 1071 | 1072 | 1073 | 1 1074 | 1075 | 1076 | 1 1077 | 1078 | 1079 | 1080 | 1081 | 1 1082 | 1083 | 1084 | 1 1085 | 1086 | 1087 | 1 1088 | 1089 | 1090 | 1091 | 1092 | ..\ 1093 | 1 1094 | 1095 | 1096 | 1097 | 1098 | Contents 1099 | 1 1100 | 1101 | 1102 | 1103 | 1104 | Contents\Resources 1105 | 1 1106 | 1107 | 1108 | 1109 | 1110 | library\lib\armeabi-v7a 1111 | 1 1112 | 1113 | 1114 | 1 1115 | 1116 | 1117 | 1 1118 | 1119 | 1120 | 1 1121 | 1122 | 1123 | 1 1124 | 1125 | 1126 | Contents\MacOS 1127 | 1 1128 | 1129 | 1130 | 0 1131 | 1132 | 1133 | 1134 | 1135 | 1 1136 | 1137 | 1138 | 1 1139 | 1140 | 1141 | 1142 | 1143 | Assets 1144 | 1 1145 | 1146 | 1147 | Assets 1148 | 1 1149 | 1150 | 1151 | 1152 | 1153 | Assets 1154 | 1 1155 | 1156 | 1157 | Assets 1158 | 1 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | 1171 | True 1172 | True 1173 | True 1174 | True 1175 | True 1176 | True 1177 | True 1178 | 1179 | 1180 | 12 1181 | 1182 | 1183 | 1184 | 1185 |
1186 | -------------------------------------------------------------------------------- /Samples/Entitlement.TemplateiOS.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <%getTaskAllowKey%> 6 | <%applicationIdentifier%> 7 | <%pushNotificationKey%> 8 | <%keychainAccessGroups%> 9 | 10 | 11 | -------------------------------------------------------------------------------- /Samples/FForm.fmx: -------------------------------------------------------------------------------- 1 | object Form5: TForm5 2 | Left = 0 3 | Top = 0 4 | Caption = 'Form5' 5 | ClientHeight = 480 6 | ClientWidth = 640 7 | FormFactor.Width = 320 8 | FormFactor.Height = 480 9 | FormFactor.Devices = [Desktop] 10 | OnCreate = FormCreate 11 | DesignerMasterStyle = 0 12 | object Layout1: TLayout 13 | Align = Top 14 | Margins.Top = 40.000000000000000000 15 | Position.Y = 40.000000000000000000 16 | Size.Width = 640.000000000000000000 17 | Size.Height = 50.000000000000000000 18 | Size.PlatformDefault = False 19 | TabOrder = 2 20 | object Button1: TButton 21 | Align = Center 22 | Size.Width = 222.000000000000000000 23 | Size.Height = 30.000000000000000000 24 | Size.PlatformDefault = False 25 | TabOrder = 0 26 | Text = 'Open embedded PDF' 27 | OnClick = Button1Click 28 | end 29 | end 30 | object Layout2: TLayout 31 | Align = Top 32 | Position.Y = 90.000000000000000000 33 | Size.Width = 640.000000000000000000 34 | Size.Height = 50.000000000000000000 35 | Size.PlatformDefault = False 36 | TabOrder = 1 37 | object Button2: TButton 38 | Align = Center 39 | Size.Width = 222.000000000000000000 40 | Size.Height = 30.000000000000000000 41 | Size.PlatformDefault = False 42 | TabOrder = 0 43 | Text = 'Open PDF by URL' 44 | OnClick = Button2Click 45 | end 46 | end 47 | object Layout3: TLayout 48 | Align = Top 49 | Position.Y = 140.000000000000000000 50 | Size.Width = 640.000000000000000000 51 | Size.Height = 50.000000000000000000 52 | Size.PlatformDefault = False 53 | TabOrder = 0 54 | object Button3: TButton 55 | Align = Center 56 | Size.Width = 222.000000000000000000 57 | Size.Height = 30.000000000000000000 58 | Size.PlatformDefault = False 59 | TabOrder = 0 60 | Text = 'Open image by URL' 61 | OnClick = Button3Click 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /Samples/FForm.pas: -------------------------------------------------------------------------------- 1 | unit FForm; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.IOUtils, 8 | FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, UExternalFileViewer; 9 | 10 | type 11 | TForm5 = class(TForm) 12 | Layout1: TLayout; 13 | Button1: TButton; 14 | Layout2: TLayout; 15 | Button2: TButton; 16 | Layout3: TLayout; 17 | Button3: TButton; 18 | procedure FormCreate(Sender: TObject); 19 | procedure Button1Click(Sender: TObject); 20 | procedure Button2Click(Sender: TObject); 21 | procedure Button3Click(Sender: TObject); 22 | private 23 | FViewer: TExternalFileViewer; 24 | public 25 | { Public declarations } 26 | end; 27 | 28 | var 29 | Form5: TForm5; 30 | 31 | implementation 32 | 33 | {$R *.fmx} 34 | 35 | procedure TForm5.FormCreate(Sender: TObject); 36 | begin 37 | self.FViewer := TExternalFileViewer.Factory(self, self); 38 | end; 39 | 40 | procedure TForm5.Button1Click(Sender: TObject); 41 | begin 42 | // open embedded PDF file 43 | self.FViewer.OpenFile( 44 | System.IOUtils.TPath.GetDocumentsPath() + PathDelim + 'svn-book.pdf' 45 | ); 46 | end; 47 | 48 | procedure TForm5.Button2Click(Sender: TObject); 49 | begin 50 | // open remote PDF by URL 51 | self.FViewer.OpenURL('https://github.com/progit/progit2/releases/download/2.1.45/progit.pdf'); 52 | end; 53 | 54 | procedure TForm5.Button3Click(Sender: TObject); 55 | begin 56 | // open remote image by URL 57 | self.FViewer.OpenURL('https://git-scm.com/images/logo@2x.png'); 58 | end; 59 | 60 | end. 61 | -------------------------------------------------------------------------------- /Samples/info.plist.TemplateiOS.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%VersionInfoPListKeys%> 6 | <%ExtraInfoPListKeys%> 7 | 8 | 9 | -------------------------------------------------------------------------------- /Samples/svn-book.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Partners/firemonkey-external-file-viewer/5d5b6a7374444bad58932b6a49ac30a16c5f0588/Samples/svn-book.pdf -------------------------------------------------------------------------------- /Source/Android/Androidapi.JNI.Environment.pas: -------------------------------------------------------------------------------- 1 | {*******************************************************} 2 | { } 3 | { CodeGear Delphi Runtime Library } 4 | { Copyright(c) 2014 Embarcadero Technologies, Inc. } 5 | { } 6 | {*******************************************************} 7 | 8 | unit Androidapi.JNI.Environment; 9 | 10 | interface 11 | 12 | {$IFDEF ANDROID} 13 | uses 14 | Androidapi.JNIBridge, 15 | Androidapi.JNI.JavaTypes; 16 | 17 | type 18 | // ===== Forward declarations ===== 19 | 20 | JEnvironment = interface;//android.os.Environment 21 | 22 | // ===== Interface declarations ===== 23 | 24 | JEnvironmentClass = interface(JObjectClass) 25 | ['{847171A2-7B65-4251-9BD3-E0BC89DE31FD}'] 26 | {class} function _GetDIRECTORY_ALARMS: JString; 27 | {class} procedure _SetDIRECTORY_ALARMS(Value: JString); 28 | {class} function _GetDIRECTORY_DCIM: JString; 29 | {class} procedure _SetDIRECTORY_DCIM(Value: JString); 30 | {class} function _GetDIRECTORY_DOCUMENTS: JString; 31 | {class} procedure _SetDIRECTORY_DOCUMENTS(Value: JString); 32 | {class} function _GetDIRECTORY_DOWNLOADS: JString; 33 | {class} procedure _SetDIRECTORY_DOWNLOADS(Value: JString); 34 | {class} function _GetDIRECTORY_MOVIES: JString; 35 | {class} procedure _SetDIRECTORY_MOVIES(Value: JString); 36 | {class} function _GetDIRECTORY_MUSIC: JString; 37 | {class} procedure _SetDIRECTORY_MUSIC(Value: JString); 38 | {class} function _GetDIRECTORY_NOTIFICATIONS: JString; 39 | {class} procedure _SetDIRECTORY_NOTIFICATIONS(Value: JString); 40 | {class} function _GetDIRECTORY_PICTURES: JString; 41 | {class} procedure _SetDIRECTORY_PICTURES(Value: JString); 42 | {class} function _GetDIRECTORY_PODCASTS: JString; 43 | {class} procedure _SetDIRECTORY_PODCASTS(Value: JString); 44 | {class} function _GetDIRECTORY_RINGTONES: JString; 45 | {class} procedure _SetDIRECTORY_RINGTONES(Value: JString); 46 | {class} function _GetMEDIA_BAD_REMOVAL: JString; 47 | {class} function _GetMEDIA_CHECKING: JString; 48 | {class} function _GetMEDIA_MOUNTED: JString; 49 | {class} function _GetMEDIA_MOUNTED_READ_ONLY: JString; 50 | {class} function _GetMEDIA_NOFS: JString; 51 | {class} function _GetMEDIA_REMOVED: JString; 52 | {class} function _GetMEDIA_SHARED: JString; 53 | {class} function _GetMEDIA_UNKNOWN: JString; 54 | {class} function _GetMEDIA_UNMOUNTABLE: JString; 55 | {class} function _GetMEDIA_UNMOUNTED: JString; 56 | {class} function init: JEnvironment; cdecl; 57 | {class} function getDataDirectory: JFile; cdecl; 58 | {class} function getDownloadCacheDirectory: JFile; cdecl; 59 | {class} function getExternalStorageDirectory: JFile; cdecl; 60 | {class} function getExternalStoragePublicDirectory(type_: JString): JFile; cdecl; 61 | {class} function getExternalStorageState: JString; cdecl; overload; 62 | // !!! this method added manually (Android 5.0+) 63 | {class} function getExternalStorageState(&File: JFile): JString; cdecl; overload; 64 | {class} function getRootDirectory: JFile; cdecl; 65 | {class} function getStorageState(path: JFile): JString; cdecl; 66 | {class} function isExternalStorageEmulated: Boolean; cdecl; 67 | {class} function isExternalStorageRemovable: Boolean; cdecl; 68 | {class} property DIRECTORY_ALARMS: JString read _GetDIRECTORY_ALARMS write _SetDIRECTORY_ALARMS; 69 | {class} property DIRECTORY_DCIM: JString read _GetDIRECTORY_DCIM write _SetDIRECTORY_DCIM; 70 | {class} property DIRECTORY_DOCUMENTS: JString read _GetDIRECTORY_DOCUMENTS write _SetDIRECTORY_DOCUMENTS; 71 | {class} property DIRECTORY_DOWNLOADS: JString read _GetDIRECTORY_DOWNLOADS write _SetDIRECTORY_DOWNLOADS; 72 | {class} property DIRECTORY_MOVIES: JString read _GetDIRECTORY_MOVIES write _SetDIRECTORY_MOVIES; 73 | {class} property DIRECTORY_MUSIC: JString read _GetDIRECTORY_MUSIC write _SetDIRECTORY_MUSIC; 74 | {class} property DIRECTORY_NOTIFICATIONS: JString read _GetDIRECTORY_NOTIFICATIONS write _SetDIRECTORY_NOTIFICATIONS; 75 | {class} property DIRECTORY_PICTURES: JString read _GetDIRECTORY_PICTURES write _SetDIRECTORY_PICTURES; 76 | {class} property DIRECTORY_PODCASTS: JString read _GetDIRECTORY_PODCASTS write _SetDIRECTORY_PODCASTS; 77 | {class} property DIRECTORY_RINGTONES: JString read _GetDIRECTORY_RINGTONES write _SetDIRECTORY_RINGTONES; 78 | {class} property MEDIA_BAD_REMOVAL: JString read _GetMEDIA_BAD_REMOVAL; 79 | {class} property MEDIA_CHECKING: JString read _GetMEDIA_CHECKING; 80 | {class} property MEDIA_MOUNTED: JString read _GetMEDIA_MOUNTED; 81 | {class} property MEDIA_MOUNTED_READ_ONLY: JString read _GetMEDIA_MOUNTED_READ_ONLY; 82 | {class} property MEDIA_NOFS: JString read _GetMEDIA_NOFS; 83 | {class} property MEDIA_REMOVED: JString read _GetMEDIA_REMOVED; 84 | {class} property MEDIA_SHARED: JString read _GetMEDIA_SHARED; 85 | {class} property MEDIA_UNKNOWN: JString read _GetMEDIA_UNKNOWN; 86 | {class} property MEDIA_UNMOUNTABLE: JString read _GetMEDIA_UNMOUNTABLE; 87 | {class} property MEDIA_UNMOUNTED: JString read _GetMEDIA_UNMOUNTED; 88 | end; 89 | 90 | [JavaSignature('android/os/Environment')] 91 | JEnvironment = interface(JObject) 92 | ['{8A8591BC-BC01-4338-91D8-2671DAB231F8}'] 93 | end; 94 | TJEnvironment = class(TJavaGenericImport) end; 95 | 96 | {$ENDIF} 97 | 98 | implementation 99 | 100 | {$IFDEF ANDROID} 101 | 102 | procedure RegisterTypes; 103 | begin 104 | TRegTypes.RegisterType('Androidapi.JNI.Environment.JEnvironment', TypeInfo(Androidapi.JNI.Environment.JEnvironment)); 105 | end; 106 | 107 | {$ENDIF} 108 | 109 | initialization 110 | {$IFDEF ANDROID} 111 | RegisterTypes; 112 | {$ENDIF} 113 | end. 114 | 115 | 116 | -------------------------------------------------------------------------------- /Source/Android/UExternalFileViewer.Android.pas: -------------------------------------------------------------------------------- 1 | {****************************************************} 2 | { } 3 | { firemonkey-external-file-viewer } 4 | { } 5 | { Copyright (C) 2018 Code Partners Pty Ltd } 6 | { } 7 | { http://www.code-partners.com } 8 | { } 9 | {****************************************************} 10 | { } 11 | { This Source Code Form is subject to the terms of } 12 | { the Mozilla Public License, v. 2.0. If a copy of } 13 | { the MPL was not distributed with this file, You } 14 | { can obtain one at } 15 | { } 16 | { http://mozilla.org/MPL/2.0/ } 17 | { } 18 | {****************************************************} 19 | unit UExternalFileViewer.Android; 20 | 21 | interface 22 | 23 | {$IFDEF ANDROID} 24 | 25 | uses 26 | System.SysUtils, System.Classes, FMX.Forms, UExternalFileViewer, System.IOUtils, 27 | Androidapi.JNI.GraphicsContentViewText, 28 | Androidapi.JNIBridge, 29 | Androidapi.JNI.JavaTypes, 30 | Androidapi.JNI.Net, 31 | Androidapi.JNI.Os, 32 | Androidapi.JNI.Util, 33 | Androidapi.Helpers, 34 | Androidapi.JNI.Environment, 35 | Androidapi.JNI.Webkit, 36 | FMX.Helpers.Android; 37 | 38 | type 39 | TAndroidExternalFileViewer = class (TExternalFileViewer) 40 | private 41 | function GetMimeType(Uri: Jnet_Uri): JString; 42 | public 43 | procedure OpenFile(Path: string); override; 44 | procedure OpenURL(URL: string); override; 45 | end; 46 | 47 | {$ENDIF} 48 | 49 | implementation 50 | 51 | {$IFDEF ANDROID} 52 | 53 | uses 54 | FMX.Dialogs; 55 | 56 | { TAndroidExternalFileViewer } 57 | 58 | procedure TAndroidExternalFileViewer.OpenFile(Path: string); 59 | var 60 | &OriginalFile, PublicDirectoryFile, PublicFile: JFile; 61 | PublicDirectoryPath, PublicPath: string; 62 | 63 | Uri: Jnet_Uri; 64 | Intent: JIntent; 65 | begin 66 | inherited; 67 | 68 | if Path.StartsWith(System.IOUtils.TPath.GetDocumentsPath()) then begin 69 | &OriginalFile := TJFile.JavaClass.init(StringToJString(Path)); 70 | 71 | PublicDirectoryPath := (JStringToString(TJEnvironment.JavaClass.getExternalStorageDirectory.getAbsolutePath) + '/Documents'); 72 | PublicPath := PublicDirectoryPath + PathDelim + ExtractFileName(Path); PublicDirectoryFile := TJFile.JavaClass.init(StringToJString(PublicDirectoryPath)); if (not PublicDirectoryFile.exists) then begin PublicDirectoryFile.mkdir; end; if (not FileExists(PublicPath)) then TFile.Copy(JStringToString(&OriginalFile.getAbsolutePath), PublicPath); 73 | PublicFile := TJFile.JavaClass.init(StringToJString(PublicPath)); 74 | end 75 | else begin 76 | PublicFile := TJFile.JavaClass.init(StringToJString(Path)); 77 | end; 78 | 79 | Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW); 80 | Uri := TJnet_Uri.JavaClass.fromFile(PublicFile); 81 | // Intent.setDataAndType(Uri, StringToJString('application/pdf')); 82 | Intent.setDataAndType(Uri, self.GetMimeType(Uri)); 83 | Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NO_HISTORY); 84 | 85 | TAndroidHelper.Activity.startActivity(Intent); 86 | end; 87 | 88 | procedure TAndroidExternalFileViewer.OpenURL(URL: string); 89 | var 90 | Intent: JIntent; 91 | Uri: Jnet_Uri; 92 | begin 93 | inherited; 94 | 95 | Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW); 96 | 97 | // Intent.setDataAndType(TJnet_Uri.JavaClass.parse(StringToJString(URL)), StringToJString('application/pdf')); 98 | 99 | Uri := TJnet_Uri.JavaClass.parse(StringToJString(URL)); 100 | Intent.setDataAndType(Uri, self.GetMimeType(Uri)); 101 | 102 | Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NO_HISTORY); 103 | 104 | TAndroidHelper.Activity.startActivity(Intent); 105 | end; 106 | 107 | function TAndroidExternalFileViewer.GetMimeType(Uri: Jnet_Uri): JString; 108 | var 109 | MimeType: JString; 110 | ContentResolver: JContentResolver; 111 | FileExtension: JString; 112 | begin 113 | // https://stackoverflow.com/a/31691791/2899073 114 | 115 | MimeType := nil; 116 | if (Uri.getScheme.equals(TJContentResolver.JavaClass.SCHEME_CONTENT)) then begin 117 | ContentResolver := TAndroidHelper.Context.getContentResolver(); 118 | MimeType := ContentResolver.getType(uri); 119 | end 120 | else begin 121 | FileExtension := TJMimeTypeMap.JavaClass.getFileExtensionFromUrl(uri.toString()); 122 | 123 | MimeType := TJMimeTypeMap.JavaClass.getSingleton().getMimeTypeFromExtension( 124 | fileExtension.toLowerCase() 125 | ); 126 | end; 127 | 128 | Result := MimeType; 129 | end; 130 | 131 | {$ENDIF} 132 | 133 | end. 134 | -------------------------------------------------------------------------------- /Source/UExternalFileViewer.pas: -------------------------------------------------------------------------------- 1 | {****************************************************} 2 | { } 3 | { firemonkey-external-file-viewer } 4 | { } 5 | { Copyright (C) 2018 Code Partners Pty Ltd } 6 | { } 7 | { http://www.code-partners.com } 8 | { } 9 | {****************************************************} 10 | { } 11 | { This Source Code Form is subject to the terms of } 12 | { the Mozilla Public License, v. 2.0. If a copy of } 13 | { the MPL was not distributed with this file, You } 14 | { can obtain one at } 15 | { } 16 | { http://mozilla.org/MPL/2.0/ } 17 | { } 18 | {****************************************************} 19 | unit UExternalFileViewer; 20 | 21 | interface 22 | 23 | uses 24 | System.SysUtils, System.Classes, FMX.Forms; 25 | 26 | type 27 | TExternalFileViewer = class (TComponent) 28 | protected 29 | FForm: TForm; 30 | 31 | constructor Create(AOwner: TComponent; AForm: TForm); reintroduce; virtual; 32 | public 33 | class function Factory(AOwner: TComponent; AForm: TForm): TExternalFileViewer; 34 | 35 | procedure OpenFile(Path: string); virtual; abstract; 36 | procedure OpenURL(URL: string); virtual; abstract; 37 | end; 38 | 39 | TDummyExternalFileViewer = class (TExternalFileViewer) 40 | public 41 | procedure OpenFile(Path: string); override; 42 | procedure OpenURL(URL: string); override; 43 | end; 44 | 45 | implementation 46 | 47 | {$IF DEFINED(ANDROID)} 48 | uses 49 | UExternalFileViewer.Android; 50 | {$ELSEIF DEFINED(IOS)} 51 | uses 52 | UExternalFileViewer.iOS; 53 | {$ENDIF} 54 | 55 | { TExternalFileViewer } 56 | 57 | constructor TExternalFileViewer.Create(AOwner: TComponent; AForm: TForm); 58 | begin 59 | inherited Create(AOwner); 60 | self.FForm := AForm; 61 | end; 62 | 63 | class function TExternalFileViewer.Factory(AOwner: TComponent; 64 | AForm: TForm): TExternalFileViewer; 65 | begin 66 | {$IF DEFINED(ANDROID)} 67 | Result := TAndroidExternalFileViewer.Create(AOwner, AForm); 68 | {$ELSEIF DEFINED(IOS)} 69 | Result := TiOSExternalFileViewer.Create(AOwner, AForm); 70 | {$ELSE} 71 | Result := TDummyExternalFileViewer.Create(AOwner, AForm); 72 | {$ENDIF} 73 | end; 74 | 75 | { TDummyExternalFileViewer } 76 | 77 | procedure TDummyExternalFileViewer.OpenFile(Path: string); 78 | begin 79 | 80 | end; 81 | 82 | procedure TDummyExternalFileViewer.OpenURL(URL: string); 83 | begin 84 | 85 | end; 86 | 87 | end. 88 | -------------------------------------------------------------------------------- /Source/UOpenURLUtils.pas: -------------------------------------------------------------------------------- 1 | {****************************************************} 2 | { } 3 | { firemonkey-external-file-viewer } 4 | { } 5 | { Copyright (C) 2018 Code Partners Pty Ltd } 6 | { } 7 | { http://www.code-partners.com } 8 | { } 9 | {****************************************************} 10 | { } 11 | { This Source Code Form is subject to the terms of } 12 | { the Mozilla Public License, v. 2.0. If a copy of } 13 | { the MPL was not distributed with this file, You } 14 | { can obtain one at } 15 | { } 16 | { http://mozilla.org/MPL/2.0/ } 17 | { } 18 | {****************************************************} 19 | unit UOpenURLUtils; 20 | 21 | interface 22 | 23 | uses 24 | System.SysUtils, System.Classes 25 | {$IFDEF ANDROID} 26 | , Androidapi.JNI.GraphicsContentViewText, 27 | Androidapi.JNI.App, 28 | Androidapi.JNIBridge, 29 | Androidapi.JNI.JavaTypes, 30 | Androidapi.Helpers, 31 | Androidapi.JNI.Net, 32 | Androidapi.JNI.Os, 33 | Androidapi.IOUtils 34 | {$ENDIF} 35 | 36 | {$IFDEF IOS} 37 | , Macapi.Helpers, 38 | iOSAPI.Foundation, 39 | iOSAPI.Helpers, 40 | iOSAPI.UIKit, 41 | iOSAPI.CoreGraphics, 42 | FMX.Helpers.iOS, 43 | FMX.Platform.iOS, 44 | Macapi.ObjectiveC, 45 | Macapi.ObjCRuntime 46 | {$ENDIF} 47 | ; 48 | 49 | procedure OpenURL(URL: string); 50 | 51 | implementation 52 | 53 | {$IF DEFINED(ANDROID)} 54 | 55 | procedure OpenURL(URL: string); 56 | var 57 | Intent: JIntent; 58 | begin 59 | Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW); 60 | Intent.setData(TJnet_Uri.JavaClass.parse(StringToJString(URL))); 61 | TAndroidHelper.Activity.startActivity(Intent); 62 | end; 63 | 64 | {$ELSEIF DEFINED(IOS)} 65 | 66 | procedure OpenURL(URL: string); 67 | var 68 | u: NSURL; 69 | begin 70 | u := TNSUrl.Wrap(TNSURL.OCClass.URLWithString(StrToNSStr(URL))); 71 | TiOSHelper.SharedApplication.openURL(u); 72 | end; 73 | 74 | {$ELSE} 75 | 76 | procedure OpenURL(URL: string); 77 | begin 78 | 79 | end; 80 | 81 | {$ENDIF} 82 | 83 | end. 84 | -------------------------------------------------------------------------------- /Source/iOS/UExternalFileViewer.iOS.pas: -------------------------------------------------------------------------------- 1 | {****************************************************} 2 | { } 3 | { firemonkey-external-file-viewer } 4 | { } 5 | { Copyright (C) 2018 Code Partners Pty Ltd } 6 | { } 7 | { http://www.code-partners.com } 8 | { } 9 | {****************************************************} 10 | { } 11 | { This Source Code Form is subject to the terms of } 12 | { the Mozilla Public License, v. 2.0. If a copy of } 13 | { the MPL was not distributed with this file, You } 14 | { can obtain one at } 15 | { } 16 | { http://mozilla.org/MPL/2.0/ } 17 | { } 18 | {****************************************************} 19 | unit UExternalFileViewer.iOS; 20 | 21 | interface 22 | 23 | {$IFDEF IOS} 24 | 25 | uses 26 | System.SysUtils, System.Classes, FMX.Forms, UExternalFileViewer, 27 | Macapi.Helpers, 28 | iOSAPI.Foundation, 29 | iOSAPI.Helpers, 30 | iOSAPI.UIKit, 31 | iOSAPI.CoreGraphics, 32 | FMX.Helpers.iOS, 33 | FMX.Platform.iOS, 34 | Macapi.ObjectiveC, 35 | Macapi.ObjCRuntime, 36 | UOpenUrlUtils; 37 | 38 | type 39 | TiOSExternalFileViewer = class; 40 | 41 | TUIDocumentInteractionControllerDelegate = class(TOCLocal, UIDocumentInteractionControllerDelegate) 42 | private 43 | [Weak] FViewer: TiOSExternalFileViewer; 44 | public 45 | constructor Create(AViewer: TiOSExternalFileViewer); 46 | 47 | function documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) 48 | : UIViewController; cdecl; 49 | function documentInteractionControllerRectForPreview(controller: UIDocumentInteractionController): CGRect; cdecl; 50 | function documentInteractionControllerViewForPreview(controller: UIDocumentInteractionController): UIView; cdecl; 51 | procedure documentInteractionControllerWillBeginPreview(controller: UIDocumentInteractionController); cdecl; 52 | procedure documentInteractionControllerDidEndPreview(controller: UIDocumentInteractionController); cdecl; 53 | procedure documentInteractionControllerWillPresentOptionsMenu(controller: UIDocumentInteractionController); cdecl; 54 | procedure documentInteractionControllerDidDismissOptionsMenu(controller: UIDocumentInteractionController); cdecl; 55 | procedure documentInteractionControllerWillPresentOpenInMenu(controller: UIDocumentInteractionController); cdecl; 56 | procedure documentInteractionControllerDidDismissOpenInMenu(controller: UIDocumentInteractionController); cdecl; 57 | [MethodName('documentInteractionController:willBeginSendingToApplication:')] 58 | procedure documentInteractionControllerWillBeginSendingToApplication(controller: UIDocumentInteractionController; 59 | willBeginSendingToApplication: NSString); cdecl; 60 | [MethodName('documentInteractionController:didEndSendingToApplication:')] 61 | procedure documentInteractionControllerDidEndSendingToApplication(controller: UIDocumentInteractionController; 62 | didEndSendingToApplication: NSString); cdecl; 63 | [MethodName('documentInteractionController:canPerformAction:')] 64 | function documentInteractionControllerCanPerformAction(controller: UIDocumentInteractionController; 65 | canPerformAction: SEL): Boolean; cdecl; 66 | [MethodName('documentInteractionController:performAction:')] 67 | function documentInteractionControllerPerformAction(controller: UIDocumentInteractionController; performAction: SEL) 68 | : Boolean; cdecl; 69 | end; 70 | 71 | TiOSExternalFileViewer = class (TExternalFileViewer) 72 | private 73 | FController: UIDocumentInteractionController; 74 | FDelegate: TUIDocumentInteractionControllerDelegate; 75 | public 76 | constructor Create(AOwner: TComponent; AForm: TForm); override; 77 | 78 | procedure OpenFile(Path: string); override; 79 | procedure OpenURL(URL: string); override; 80 | end; 81 | 82 | {$ENDIF} 83 | 84 | implementation 85 | 86 | {$IFDEF IOS} 87 | 88 | { TiOSExternalFileViewer } 89 | 90 | constructor TiOSExternalFileViewer.Create(AOwner: TComponent; AForm: TForm); 91 | begin 92 | inherited; 93 | end; 94 | 95 | procedure TiOSExternalFileViewer.OpenFile(Path: string); 96 | var 97 | Url: NSUrl; 98 | begin 99 | Url := TNSUrl.Wrap(TNSURL.OCClass.fileURLWithPath(StrToNSStr(Path))); 100 | 101 | self.FController := TUIDocumentInteractionController.Wrap( 102 | TUIDocumentInteractionController.OCClass.interactionControllerWithURL(Url) 103 | ); 104 | FDelegate := TUIDocumentInteractionControllerDelegate.Create(self); 105 | self.FController.setDelegate(self.FDelegate.GetObjectID); 106 | 107 | self.FController.presentPreviewAnimated(true); 108 | end; 109 | 110 | procedure TiOSExternalFileViewer.OpenURL(URL: string); 111 | begin 112 | UOpenUrlUtils.OpenURL(URL); 113 | end; 114 | 115 | { TUIDocumentInteractionControllerDelegate } 116 | 117 | constructor TUIDocumentInteractionControllerDelegate.Create( 118 | AViewer: TiOSExternalFileViewer); 119 | begin 120 | inherited Create; 121 | 122 | self.FViewer := AViewer; 123 | end; 124 | 125 | function TUIDocumentInteractionControllerDelegate.documentInteractionControllerCanPerformAction( 126 | controller: UIDocumentInteractionController; canPerformAction: SEL): Boolean; 127 | begin 128 | Result := true; 129 | end; 130 | 131 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerDidDismissOpenInMenu( 132 | controller: UIDocumentInteractionController); 133 | begin 134 | 135 | end; 136 | 137 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerDidDismissOptionsMenu( 138 | controller: UIDocumentInteractionController); 139 | begin 140 | 141 | end; 142 | 143 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerDidEndPreview( 144 | controller: UIDocumentInteractionController); 145 | begin 146 | 147 | end; 148 | 149 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerDidEndSendingToApplication( 150 | controller: UIDocumentInteractionController; 151 | didEndSendingToApplication: NSString); 152 | begin 153 | 154 | end; 155 | 156 | function TUIDocumentInteractionControllerDelegate.documentInteractionControllerPerformAction( 157 | controller: UIDocumentInteractionController; performAction: SEL): Boolean; 158 | begin 159 | Result := true; 160 | end; 161 | 162 | function TUIDocumentInteractionControllerDelegate.documentInteractionControllerRectForPreview( 163 | controller: UIDocumentInteractionController): CGRect; 164 | begin 165 | 166 | end; 167 | 168 | function TUIDocumentInteractionControllerDelegate.documentInteractionControllerViewControllerForPreview( 169 | controller: UIDocumentInteractionController): UIViewController; 170 | var 171 | h: TiOSWindowHandle; 172 | w: UIWindow; 173 | v: UIViewController; 174 | begin 175 | h := WindowHandleToPlatform(self.FViewer.FForm.Handle); 176 | w := h.Wnd; 177 | v := w.rootViewController; 178 | 179 | Result := v; 180 | end; 181 | 182 | function TUIDocumentInteractionControllerDelegate.documentInteractionControllerViewForPreview( 183 | controller: UIDocumentInteractionController): UIView; 184 | begin 185 | 186 | end; 187 | 188 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerWillBeginPreview( 189 | controller: UIDocumentInteractionController); 190 | begin 191 | 192 | end; 193 | 194 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerWillBeginSendingToApplication( 195 | controller: UIDocumentInteractionController; 196 | willBeginSendingToApplication: NSString); 197 | begin 198 | 199 | end; 200 | 201 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerWillPresentOpenInMenu( 202 | controller: UIDocumentInteractionController); 203 | begin 204 | 205 | end; 206 | 207 | procedure TUIDocumentInteractionControllerDelegate.documentInteractionControllerWillPresentOptionsMenu( 208 | controller: UIDocumentInteractionController); 209 | begin 210 | 211 | end; 212 | 213 | {$ENDIF} 214 | 215 | end. 216 | --------------------------------------------------------------------------------