| 
					
				 | 
			
			
				@@ -0,0 +1,3600 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+unit FlyFilesUtils;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(* ************************************************ *)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(*                         *)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(*  设计:爱吃猪头肉 & Flying Wang 2013-11-30   *)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(*      上面的版权声明请不要移除。      *)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(*      Ver 1.0.2014.808            *)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(*                         *)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(* ************************************************ *)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2014.1108
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//支持 UTF8 的检查。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2014.908
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//支持 XE7。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2014.808
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//增加函数 IsPadOrPC。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2014.805
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//增加安卓下的获取 内存 SD 卡空间的函数。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2014.419
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//增加对 XE6 的支持。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2014.225
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//增加对 JNI 的接口查找功能。不完善。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2013.1219
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//在 亚瑟(Arthur)  3140223 的启发下,增加了更多的 SD 目录。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2013.1217
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//增加一个 FindSDCardSubPath 函数,用于查找指定的目录。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//1.0.2013.1206
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//增加 [佛山]N.E(1024317)  9:36:38 提供的几个 SD 卡的路径。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+interface
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uses System.SysUtils,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.Classes,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNIBridge,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.IOUtils,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Winapi.Windows,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Posix.Dlfcn, Posix.Fcntl, Posix.SysStat, Posix.SysTime, Posix.SysTypes, Posix.Locale,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF PC_MAPPED_EXCEPTIONS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.Internal.Unwinder,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF PC_MAPPED_EXCEPTIONS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MACOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Macapi.Mach, Macapi.CoreServices, Macapi.CoreFoundation,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF MACOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.SysConst,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.IOUtils;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Error_NotFoundFileManager_Str: string = 'Not Found FileManager.';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  返回大小写敏感的文件或路径名称
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="FileName">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  文件或路径名
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="RootPath">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  <para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	    检查路径的根目录
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  </para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  <para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	    当大小写检查到此目录时停止,不再继续检查。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  </para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetCaseSensitiveFileName(const FileName: string; RootPath: string = ''): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	  外置设备的数量
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  OTGDeivceCount = 16;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	  USB 磁盘,例如 U 盘、移动硬盘等
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UsbDiskStartIndex = 255;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	  外置光驱
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CDROMStartIndex = 255 + OTGDeivceCount;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	  默认的删除等待时间,单位微秒
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DeleteDirectories_WaitMinSecond = 2000;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  检查 SD 卡或路径是否可用
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function isPathCanUseNow(const PathOrDir: string; const Default: Boolean = True): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  检查 SD 卡或路径是否写入
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function TestPathCanWrite(const PathOrDir: string): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取 手机存储 或 SD 卡的路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Index">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  0 为 手机存储 1 为 SD 卡
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  <para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	    如果找到,返回路径。带 / 或 \
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  </para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  <para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	    没找到,返回一个错误的路径。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  </para>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetSDCardPath(Index: Integer = 0): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  查找 手机存储 或 SD 卡上的某个路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="SubPath">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  被查找的子路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Index">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  0 为 手机存储 1 为 SD 卡
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  如果找到,返回路径。带 / 或 \ 没找到,返回一个错误的路径。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function FindSDCardSubPath(SubPath: string; Index: Integer = 0): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取当成工程的运行路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetAppPath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  查找一个路径下的指定格式的文件
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Path">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  路径,必须用通配符结束。例如 /*
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Attr">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  需要查找的文件的属性
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="List">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  返回一个文件名或目录名的列表
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="JustFile">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  是否只查找文件
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  无意义
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function BuildFileListInAPath(const Path: string; const Attr: Integer; const List: TStrings;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  JustFile: Boolean = False): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  查找一个路径下的指定格式的文件
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Path">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  路径,必须用通配符结束。例如 /*
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Attr">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  需要查找的文件的属性
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="JustFile">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  是否只查找文件
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  返回换行分割的文件名或目录的列表
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function BuildFileListInAPath(const Path: string; const Attr: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  JustFile: Boolean = False): string; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  查找指定路径下的文件
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="DirName">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="SearchFilter">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  通配符组成的查找格式
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="FileAttribs">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  需要查找的文件的属性
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="isIncludeSubDirName">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  是否包含子目录的名字
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Recursion">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  是否递归找子目录
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="FullName">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  是否返回完整路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  返回换行分割的文件名或目录的列表
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetFileNamesFromDirectory(const DirName: string; const SearchFilter: string = '*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const FileAttribs: Integer = faAnyFile; const isIncludeSubDirName: Boolean = False; const Recursion: Boolean = False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const FullName: Boolean = False): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//可以用 TDirectory.Delete 代替下面的功能。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  删除目录下指定的文件
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="Source">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  被删除的文件路径,可以使用通配符
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="AbortOnFailure">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  失败时是否退出
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="YesToAll">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  删掉所有文件,包括只读的。仅 WIN32 下有效。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="WaitMinSecond">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  检查文件删除的等待时间,单位 微秒
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  是否删除完成
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</returns>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function DeleteDirectoryByEcho(const Source: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AbortOnFailure: Boolean = False; YesToAll: Boolean = True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WaitMinSecond: Integer = DeleteDirectories_WaitMinSecond): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取指定路径的总存储大小
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetTotalSpaceSize(Path: string = PathDelim): UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取指定路径的可以使用的存储大小
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetAvailableSpaceSize(Path: string = PathDelim): UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取指定路径的剩余(包括不可使用的)存储大小
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetFreeSpaceSize(Path: string = PathDelim): UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取总内存大小
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   感谢[上海]故国(370620516)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetTotalMemorySize: UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取剩余内存大小
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   感谢[上海]故国(370620516)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetFreeMemorySize: UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  安卓 IOS 返回是否是 PAD(平板)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   其他平台,返回 True
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   很多手机的 DPI 是错的,所以获取的尺寸也就不正常了,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   所以个别手机会被识别成 PAD。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsPadOrPC: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//function IsPadOrPC(MiniScreenInches: Single = 6.2): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//function IsPad: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  在其他 APP 中打开文件。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function OpenFileOnExtApp(const FileName: string; Https: Boolean = True): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function NowGMT_UTC: TDateTime;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取完整 URL 的 Encode 结果。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   Just UTF8
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function EncodeURLWithSchemeOrProtocol(const URL: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//上面是跨平台函数。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//下面是平台函数。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetVolumePaths: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetExternalStoragePath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExterStoragePathCanRead: Boolean = True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExterStoragePathCanWrite: Boolean = True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  SDMountedMessageReceived: Boolean = False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetExterStoragePath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetInnerStoragePath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  It check SDCard0 Removable
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetIsExternalStorageRemovable: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   很多手机的 DPI 是错的,所以获取的尺寸也就不正常了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetScreenClientInches: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  获取安卓下剩余内存大小
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//function GetActiveMemorySize: UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  查找一个 JAVA 类是否可以使用
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	<param name="NamePath">
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	  类的全路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///	</param>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsCanFindJavaClass(const NamePath: string): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsCanFindJavaMethod(const MethodName, Signature: string; const CalssNamePath: string = ''): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsCanFindJavaStaticMethod(const MethodName, Signature: string; const CalssNamePath: string = ''): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TGetFileNameListener = reference to procedure(const IsOK: Boolean; const FileName:string);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TGetFileNameLIsternerMethod = procedure (const IsOK: Boolean; const FileName:string) of object;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function OpenFileDialog(Title, FileExtension:string; GetFileNameCallBack: TGetFileNameListener): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function OpenFileDialog(Title, FileExtension:string; GetFileNameCallBack: TGetFileNameLIsternerMethod): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function CheckPermission(const APermissionName: string): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  C_android_permission_EXTERNAL_STORAGE = 'android.permission.WRITE_EXTERNAL_STORAGE';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  C_android_permission_WRITE_MEDIA = 'android.permission.WRITE_MEDIA_STORAGE';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function CanWriteExterStorage: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+///   更新相册
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+procedure UpdateAlbum(FileNames: string);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function ReadNoSizeFileToString(const AFileName: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function ReadFileToString(const AFileName: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+implementation
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uses
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 27.0} // >= XE6
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.Helpers,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FMX.Helpers.Android,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 28.0} // < XE7
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FMX.Helpers.Android,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.Jni,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.Environment,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.StatFs,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.Stream2,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.ActivityManager,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.JavaTypes,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.NativeActivity,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.GraphicsContentViewText,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.Util,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.android.os.storage.StorageManager,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.java.lang.FlyUtils,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.Webkit,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Androidapi.JNI.Embarcadero,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.App,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.Net,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.Media,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.Provider,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  iOSapi.Foundation,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Macapi.ObjectiveC,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FMX.Helpers.iOS,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  iOSapi.UIDevice2,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Winapi.ShellApi,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FMX.Dialogs,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 29.0} //  XE8
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.NetEncoding,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IdURI,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.Rtti,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.TypInfo,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.Messaging,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  System.Math;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//来自 inc 内部的 类型。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ Used by other time functions.  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tm = record
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_sec: Integer;            // Seconds. [0-60] (1 leap second)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_min: Integer;            // Minutes. [0-59]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_hour: Integer;           // Hours.[0-23]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_mday: Integer;           // Day.[1-31]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_mon: Integer;            // Month.[0-11]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_year: Integer;           // Year since 1900
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_wday: Integer;           // Day of week [0-6] (Sunday = 0)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_yday: Integer;           // Days of year [0-365]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_isdst: Integer;          // Daylight Savings flag [-1/0/1]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_gmtoff: LongInt;         // Seconds east of UTC
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_zone: MarshaledAString;  // Timezone abbreviation
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {$EXTERNALSYM tm}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Ptm = ^tm;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSEIF DEFINED(ANDROID)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ Used by other time functions.  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tm = record
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_sec: Integer;            // Seconds. [0-60] (1 leap second)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_min: Integer;            // Minutes. [0-59]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_hour: Integer;           // Hours.[0-23]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_mday: Integer;           // Day.[1-31]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_mon: Integer;            // Month.[0-11]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_year: Integer;           // Year since 1900
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_wday: Integer;           // Day of week [0-6] (Sunday = 0)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_yday: Integer;           // Days of year [0-365]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_isdst: Integer;          // Daylight Savings flag [-1/0/1]
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_gmtoff: LongInt;         // Seconds east of UTC
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tm_zone: MarshaledAString;         // Timezone abbreviation
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {$EXTERNALSYM tm}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Ptm = ^tm;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//来自 inc 的函数定义。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF UNDERSCOREIMPORTNAME}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _PU = '_';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _PU = '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  libc        = '/usr/lib/libc.dylib';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  libpthread  = '/usr/lib/libpthread.dylib';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  libiconv    = '/usr/lib/libiconv.dylib';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  libdl       = '/usr/lib/libdl.dylib';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF not Declared(_PU)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // On Mac OSX, cdecl names have a preceeding underscore
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // if x86 native backend.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {$IF Defined(UNDERSCOREIMPORTNAME)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _PU = '_';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _PU = '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {$EXTERNALSYM _PU}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFNDEF IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _INODE_SUFFIX = '$INODE64';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _INODE_SUFFIX = '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF !IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {$EXTERNALSYM _INODE_SUFFIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//具体函数定义开始。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function _system(Name: MarshaledAString): Integer; cdecl;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  external libc name _PU + 'system';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function tempnam(const Path: MarshaledAString; const Prefix: MarshaledAString): MarshaledAString; cdecl;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  external libc name _PU + 'tempnam';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$EXTERNALSYM tempnam}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+procedure free(p: Pointer); cdecl;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  external libc name _PU + 'free';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$EXTERNALSYM free}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function gettimeofday(var timeval: timeval; timezone: Pointer): Integer; cdecl;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  external libc name _PU + 'gettimeofday';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$EXTERNALSYM gettimeofday}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function gmtime_r(var Timer: time_t; var UnixTime: tm): Ptm; cdecl;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  external libc name _PU + 'gmtime_r';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$EXTERNALSYM gmtime_r}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//可以开始写函数了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function NowGMT_UTC: TDateTime;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SystemTime: TSystemTime;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetSystemTime(SystemTime);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := EncodeDate(SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay) +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    EncodeTime(SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  T: time_t;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TV: timeval;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UT: tm;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gettimeofday(TV, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  T := TV.tv_sec;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gmtime_r(T, UT);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := EncodeDate(UT.tm_year + 1900, UT.tm_mon + 1, UT.tm_mday) +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    EncodeTime(UT.tm_hour, UT.tm_min, UT.tm_sec, TV.tv_usec div 1000);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function EncodeURLWithSchemeOrProtocol(const URL: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Protocol: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AURL: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AIndex: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 29.0} //  XE8
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   AURL := URL.Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   Protocol := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   AIndex := AURL.IndexOf('//');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   if AIndex > 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     Protocol := AURL.Substring(0, AIndex + 1); // has /
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     AURL := AURL.Substring(AIndex + 1); // has /
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   Result := Protocol + TNetEncoding.URL.EncodePath(AURL);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   Result := TIdURI.URLEncode(Result);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function EncodeURLWithOutSchemeOrProtocol(const URL: string; Https: Boolean = True): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := URL;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Result.Substring(0, 1) <> '/' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := '/' + Result;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := 'file://' + Result;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Https then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := 'https://' + URL;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := 'http://' + URL;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := EncodeURLWithSchemeOrProtocol(Result);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function OpenFileOnExtApp(const FileName: string; Https: Boolean = True): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Intent: JIntent;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileExtension: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mime: JMimeTypeMap;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MIMEType: JString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempStr,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileToOpen: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJFile: JFile;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJUri: Jnet_Uri;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// There may be an issue with the geo: prefix and URLEncode.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// will need to research
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileName = '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileExtension := AnsiLowerCase(ExtractFileExt(FileName));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileExtension = '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mime := TJMimeTypeMap.JavaClass.getSingleton();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MIMEType := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if mime <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MIMEType := mime.getMimeTypeFromExtension(StringToJString(FileExtension.Substring(1)));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if MIMEType <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 调用相应程序打开当前程序
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Intent := TJIntent.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //TempStr := IncludeTrailingPathDelimiter(TPath.GetDocumentsPath)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TempStr := IncludeTrailingPathDelimiter(TPath.GetHomePath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 33.0} //  RAD10.3
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if FileExists(FileName) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FileToOpen := FileName;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FileToOpen := EncodeURLWithOutSchemeOrProtocol(FileName, Https);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Pos(TempStr, FileToOpen) = 1 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AJFile := TJFile.JavaClass.init(StringToJString(FileToOpen));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AJUri := TAndroidHelper.JFileToJURI(AJFile);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FileToOpen := EncodeURLWithOutSchemeOrProtocol(FileName, Https);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AJUri := StrToJURI(FileToOpen);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Intent.setDataAndType(AJUri, MIMEType);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      SharedActivity.startActivity(Intent);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NSU: NSUrl;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AURL: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AURL := EncodeURLWithOutSchemeOrProtocol(FileName, Https);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // iOS doesn't like spaces, so URL encode is important.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NSU := StrToNSUrl(AURL);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if TOSVersion.Check(9) or SharedApplication.canOpenURL(NSU) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := SharedApplication.openUrl(NSU);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AURL: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AURL := EncodeURLWithOutSchemeOrProtocol(FileName, Https);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ShellExecute(GetActiveWindow, 'open', PChar(AURL), '', '', SW_MAXIMIZE);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  M:TMarshaller;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AURL: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //AURL := 'open -a Safari ' +  EncodeURLWithOutSchemeOrProtocol(AURL);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AURL := 'open ' +  EncodeURLWithOutSchemeOrProtocol(FileName, Https);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _system(M.AsAnsi(AURL, CP_UTF8).ToPointer);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  raise Exception.Create('Not supported!');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsPadOrPC: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := IsPad;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF IOS or MACOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ScreenInches2,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ScreenInches1,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  x,y: Double;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  dm: JDisplayMetrics;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  dm := GetJDisplayMetrics;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if dm = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  x := dm.widthPixels;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  y := dm.heightPixels;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    ScreenInches1 := Sqrt((x * x / dm.xdpi / dm.xdpi) + (y * y / dm.ydpi / dm.ydpi));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    ScreenInches2 := Sqr(x * x + y * Y ) / dm.densityDpi;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := ScreenInches1 >= MiniScreenInches;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if Result then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := ScreenInches2 >= MiniScreenInches;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IsTablet: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IsTablet := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  CallInUIThreadAndWaitFinishing(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  procedure
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    IsTablet := SharedActivity.getResources.getConfiguration.screenLayout and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TJConfiguration.JavaClass.SCREENLAYOUT_SIZE_MASK >= TJConfiguration.JavaClass.SCREENLAYOUT_SIZE_LARGE;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := IsTablet;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsPad: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //code by [龟山]Aone(1467948783)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := TOSVersion.Check(6, 1) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               (GetSystemMetrics(SM_TABLETPC) <> 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               ((GetSystemMetrics(SM_DIGITIZER) and NID_MULTI_INPUT) = NID_MULTI_INPUT);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := IsPad;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF IOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE} //IF DEFINED(IOS) or DEFINED(MACOS)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := IsPadOrPC;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF IOS or MACOS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetTotalMemorySize: UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := TUIDevice2.Wrap(TUIDevice2.OCClass.currentDevice).totalMemory;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := NSRealMemoryAvailable;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpBuffer : TMEMORYSTATUSEX;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ZeroMemory(@lpBuffer, Sizeof(TMEMORYSTATUSEX));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpBuffer.dwLength := Sizeof(TMEMORYSTATUSEX);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GlobalMemoryStatusEx(lpBuffer);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := lpBuffer.ullTotalPhys;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Mgr: JActivityManager;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MgrNative: JObject;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MemInfo: JActivityManager_MemoryInfo;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AStrings: TStringList;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempValue: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AReader: JReader;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ABufferedReader: JBufferedReader;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MgrNative :=
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 30.0} // >=RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TAndroidHelper.Context
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SharedActivityContext
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .getSystemService(TJContext.JavaClass.ACTIVITY_SERVICE);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if MgrNative <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Mgr := TJActivityManager.Wrap((MgrNative as ILocalObject).GetObjectID);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MemInfo := TJActivityManager_MemoryInfo.JavaClass.init;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Mgr.getMemoryInfo(MemInfo);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := UInt64(MemInfo.totalMem);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //API level < 16
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := UInt64(MemInfo.availMem);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if FileExists('/proc/meminfo') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AStrings := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AStrings.LineBreak := sLineBreak;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AStrings.NameValueSeparator := ':';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AStrings.Clear;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AReader := TJFileReader.JavaClass.init(StringToJString('/proc/meminfo')) as JReader;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ABufferedReader := TJBufferedReader.JavaClass.init(AReader);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          repeat
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TempValue := JStringToString(ABufferedReader.readLine);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if TempValue <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              AStrings.Add(TempValue);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          until (not ABufferedReader.ready);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ABufferedReader.close;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TempValue := AStrings.Values['MemTotal'].Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AStrings.Clear;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AStrings.NameValueSeparator := ' ';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AStrings.Add(TempValue.Trim);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TempValue := AStrings.Names[0];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//          ShowMessage(TempValue);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := StrToInt64Def(TempValue, Result div 1024) * 1024;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          FreeAndNil(AStrings);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetFreeMemorySize: UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //Result := Max(0, GetTotalMemorySize -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //  TUIDevice2.Wrap(TUIDevice2.OCClass.currentDevice).userMemory);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := NSRealMemoryAvailable;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpBuffer : TMEMORYSTATUSEX;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ZeroMemory(@lpBuffer, Sizeof(TMEMORYSTATUSEX));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpBuffer.dwLength := Sizeof(TMEMORYSTATUSEX);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GlobalMemoryStatusEx(lpBuffer);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := lpBuffer.ullAvailPhys;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Mgr: JActivityManager;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MgrNative: JObject;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MemInfo: JActivityManager_MemoryInfo;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MgrNative :=
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 30.0} // >=RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TAndroidHelper.Context
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SharedActivityContext
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .getSystemService(TJContext.JavaClass.ACTIVITY_SERVICE);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if MgrNative <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Mgr := TJActivityManager.Wrap((MgrNative as ILocalObject).GetObjectID);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MemInfo := TJActivityManager_MemoryInfo.JavaClass.init;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Mgr.getMemoryInfo(MemInfo);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := UInt64(MemInfo.availMem);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetTotalSpaceSize(Path: string = PathDelim): UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Dict: NSDictionary;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  P: Pointer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FoundationFwk: string = '/System/Library/Frameworks/Foundation.framework/Foundation';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Dict := TNSFileManager.Wrap(TNSFileManager.OCClass.defaultManager).attributesOfFileSystemForPath(NSStr(Path), nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Dict = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  P := Dict.objectForKey((CocoaNSStringConst(FoundationFwk, 'NSFileSystemSize') as ILocalObject).GetObjectID);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if P <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := TNSNumber.Wrap(P).unsignedLongLongValue;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpFreeBytesAvailableToCaller,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfBytes,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfFreeBytes: Int64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfBytes := MaxInt;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if GetDiskFreeSpaceEx(pchar(ExtractFileDrive(Path)),
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lpFreeBytesAvailableToCaller,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lpTotalNumberOfBytes, @lpTotalNumberOfFreeBytes) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := UInt64(lpTotalNumberOfBytes);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJFile: JFile;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJStatFs: JStatFs;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJFile := TJFile.JavaClass.init(StringToJString(Path));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if AJFile = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJStatFs := TJStatFs.JavaClass.init(AJFile.getPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if AJStatFs = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := UInt64(AJStatFs.getBlockSize) * UInt64(AJStatFs.getBlockCount);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetFreeSpaceSize(Path: string = PathDelim): UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Dict: NSDictionary;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  P: Pointer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FoundationFwk: string = '/System/Library/Frameworks/Foundation.framework/Foundation';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Dict := TNSFileManager.Wrap(TNSFileManager.OCClass.defaultManager).attributesOfFileSystemForPath(NSStr(Path), nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Dict = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  P := Dict.objectForKey((CocoaNSStringConst(FoundationFwk, 'NSFileSystemFreeSize') as ILocalObject).GetObjectID);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if P <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := TNSNumber.Wrap(P).unsignedLongLongValue;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpFreeBytesAvailableToCaller,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfBytes,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfFreeBytes: Int64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfFreeBytes := MaxInt;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if GetDiskFreeSpaceEx(pchar(ExtractFileDrive(Path)),
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lpFreeBytesAvailableToCaller,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lpTotalNumberOfBytes, @lpTotalNumberOfFreeBytes) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := UInt64(lpTotalNumberOfFreeBytes);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJFile: JFile;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJStatFs: JStatFs;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJFile := TJFile.JavaClass.init(StringToJString(Path));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if AJFile = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJStatFs := TJStatFs.JavaClass.init(AJFile.getPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if AJStatFs = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := UInt64(AJStatFs.getBlockSize) * UInt64(AJStatFs.getFreeBlocks);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetAvailableSpaceSize(Path: string = PathDelim): UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF DEFINED(IOS) or DEFINED(MACOS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := GetFreeSpaceSize(Path);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpFreeBytesAvailableToCaller,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfBytes,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpTotalNumberOfFreeBytes: Int64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lpFreeBytesAvailableToCaller := MaxInt;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if GetDiskFreeSpaceEx(pchar(ExtractFileDrive(Path)),
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lpFreeBytesAvailableToCaller,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lpTotalNumberOfBytes, @lpTotalNumberOfFreeBytes) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := UInt64(lpFreeBytesAvailableToCaller);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJFile: JFile;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJStatFs: JStatFs;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(Path) or FileExists(Path) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create('Path " ' + Path +  '" not found.');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJFile := TJFile.JavaClass.init(StringToJString(Path));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if AJFile = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AJStatFs := TJStatFs.JavaClass.init(AJFile.getPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if AJStatFs = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := UInt64(AJStatFs.getBlockSize) * UInt64(AJStatFs.getAvailableBlocks);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function CanWriteExterStorage: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := CheckPermission(C_android_permission_EXTERNAL_STORAGE);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if Result and TOSVersion.Check(4) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// // 没有效果,而且返回 总是 False
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := CheckPermission(C_android_permission_WRITE_MEDIA);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//copy form FMX.AddressBook.Android;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function CheckPermission(const APermissionName: string): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PackageName: JString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PackageName := TAndroidHelper.Context.getPackageName;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if TOSVersion.Check(6) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := TAndroidHelper.Context.checkSelfPermission(StringToJString(APermissionName)) =
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      TJPackageManager.JavaClass.PERMISSION_GRANTED;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := TAndroidHelper.Context.getPackageManager.checkPermission(StringToJString(APermissionName), PackageName) =
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TJPackageManager.JavaClass.PERMISSION_GRANTED;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function isExternalStorageDocument(URI: Jnet_Uri): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if URI = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := URI.getAuthority.equals(StringToJString('com.android.externalstorage.documents'));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function isDownloadsDocument(URI: Jnet_Uri): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if URI = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := URI.getAuthority.equals(StringToJString('com.android.providers.downloads.documents'));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function isMediaDocument(URI: Jnet_Uri): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if URI = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := URI.getAuthority.equals(StringToJString('com.android.providers.media.documents'));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FILE_SELECT_CODE = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FMessageChooserID: Integer = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FGetFileNameCallBack1: TGetFileNameListener;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FGetFileNameCallBack2: TGetFileNameLIsternerMethod;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+procedure HandleActivityMessageforChooser(const Sender: TObject; const M: TMessage);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MediaDocument,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ExternalStorageDocument,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IsOK: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DocType,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DocIDs,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileScheme,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileName:string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  URI: Jnet_Uri;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cursor: JCursor;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  projection: TJavaObjectArray<JString>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  column_index: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DocIDInfos: TArray<string>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempDocIDStr: JString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  selection: JString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  selectionArgs: TJavaObjectArray<JString>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IsOK := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileName := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IsOK := M is TMessageResultNotification;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if IsOK and (TMessageResultNotification(M).RequestCode = FILE_SELECT_CODE) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    IsOK := (TMessageResultNotification(M).ResultCode = TJActivity.JavaClass.RESULT_OK);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    IsOK := TMessageResultNotification(M).Value <> nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    URI := TMessageResultNotification(M).Value.getData;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    IsOK := URI <> nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileName := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FileScheme := JStringToString(URI.getScheme);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if TOSVersion.Check(4, 4) and TJDocumentsContract.JavaClass.isDocumentUri(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 30.0} // >=RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TAndroidHelper.Context
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      SharedActivityContext
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      , URI) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //http://blog.csdn.net/u011200844/article/details/43703593
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ExternalStorageDocument := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      MediaDocument := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      selection := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      selectionArgs := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      IsOK := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if isDownloadsDocument(URI) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        TempDocIDStr := TJDocumentsContract.JavaClass.getDocumentId(URI);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        URI := TJContentUris.JavaClass.withAppendedId(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TJnet_Uri.JavaClass.parse(StringToJString('content://downloads/public_downloads')),
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TJLong.JavaClass.valueOf(TempDocIDStr).longValue);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //后面会继续处理。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ExternalStorageDocument := isExternalStorageDocument(URI);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not ExternalStorageDocument then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          MediaDocument := isMediaDocument(URI);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ExternalStorageDocument or MediaDocument then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DocIDs := JStringToString(TJDocumentsContract.JavaClass.getDocumentId(URI));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DocIDInfos := DocIDs.Split([':']);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if Length(DocIDInfos) > 1 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          DocType := DocIDInfos[0];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if ExternalStorageDocument then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if SameText(DocType, 'primary') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              FileName := GetSDCardPath(0) + DocIDInfos[1];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              IsOK := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              //后面会继续处理。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else if MediaDocument then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if SameText(DocType, 'image') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              URI := TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              IsOK := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else if SameText(DocType, 'video') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              URI := TJVideo_Media.JavaClass.EXTERNAL_CONTENT_URI;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              IsOK := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else if SameText(DocType, 'audio') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              URI := TJAudio_Media.JavaClass.EXTERNAL_CONTENT_URI;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              IsOK := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              selection := StringToJString('_id=?');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              selectionArgs := TJavaObjectArray<JString>.Create(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              selectionArgs.Items[0] := StringToJString(DocIDInfos[1]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              IsOK := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              //后面会继续处理。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      IsOK := SameText('file', FileScheme);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if IsOK and FileName.IsEmpty then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FileName := JStringToString(URI.getPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if not IsOK then       
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    IsOK := SameText('content', FileScheme);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      IsOK := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      projection := TJavaObjectArray<JString>.Create(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      projection.Items[0] := StringToJString('_data');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cursor :=
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 30.0} // >=RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TAndroidHelper.Context
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          SharedActivityContext
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          .getContentResolver().query(URI, projection, selection, selectionArgs, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (cursor <> nil) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            column_index := cursor.getColumnIndexOrThrow(StringToJString('_data'));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if cursor.moveToFirst then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              FileName := JStringToString(cursor.getString(column_index));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              IsOK := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        IsOK := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    if not IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      FileName := JStringToString(URI.getPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      FileName := FileName.Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      IsOK := not FileName.IsEmpty;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      if not IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//          IsOK := FileName.IndexOf(PathDelim) <> -1;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FileName := FileName.Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    IsOK := not FileName.IsEmpty;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if IsOK then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+////    IsOK := FileExists(FileName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    IsOK := FileName.IndexOf(PathDelim) <> -1;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Assigned(FGetFileNameCallBack1) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FGetFileNameCallBack1(IsOK, FileName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Assigned(FGetFileNameCallBack2) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FGetFileNameCallBack2(IsOK, FileName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function InternalOpenFileDialog(Title, FileExtension:string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetFileNameCallBack1: TGetFileNameListener;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetFileNameCallBack2: TGetFileNameLIsternerMethod): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MIMEType: JString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mime: JMimeTypeMap;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Intent: JIntent;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IntentChooser: JIntent;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sMIMEType: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FGetFileNameCallBack1 := GetFileNameCallBack1;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FGetFileNameCallBack2 := GetFileNameCallBack2;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileExtension.Substring(0,1) = '.' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FileExtension := FileExtension.Substring(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileExtension  = '*.*' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FileExtension := '*/*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MIMEType := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sMIMEType := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileExtension = 'file/*' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sMIMEType := 'file/*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if FileExtension = '*' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if TOSVersion.Check(4, 4) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sMIMEType := '*/*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sMIMEType := 'file/*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if FileExtension = '*/*' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sMIMEType := '*/*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if FileExtension = '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sMIMEType := '*/*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FileExtension := AnsiLowerCase(FileExtension);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //http://www.oschina.net/code/snippet_1269559_25060
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    mime := TJMimeTypeMap.JavaClass.getSingleton;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if mime <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      MIMEType := mime.getMimeTypeFromExtension(StringToJString(FileExtension));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if MIMEType <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sMIMEType := JStringToString(MIMEType).Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if sMIMEType.IsEmpty then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sMIMEType := '*/*'; // File/* 有时候打不开
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //http://www.cnblogs.com/linlf03/archive/2013/08/19/3267732.html
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if TOSVersion.Check(4, 4) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_OPEN_DOCUMENT);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_GET_CONTENT);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Intent.setType(StringToJString(sMIMEType));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Intent.addCategory(TJIntent.JavaClass.CATEGORY_OPENABLE);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IntentChooser := TJIntent.JavaClass.createChooser(Intent, StrToJCharSequence(Title));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FMessageChooserID <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification, FMessageChooserID);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FMessageChooserID := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FMessageChooserID := TMessageManager.DefaultManager.SubscribeToMessage(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TMessageResultNotification, HandleActivityMessageforChooser);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 30.0} // >=RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TAndroidHelper.Activity
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SharedActivity
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .startActivityForResult(IntentChooser, FILE_SELECT_CODE);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise Exception.Create(Error_NotFoundFileManager_Str);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function OpenFileDialog(Title, FileExtension:string; GetFileNameCallBack: TGetFileNameListener): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := InternalOpenFileDialog(Title, FileExtension, GetFileNameCallBack, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function OpenFileDialog(Title, FileExtension:string; GetFileNameCallBack: TGetFileNameLIsternerMethod): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := InternalOpenFileDialog(Title, FileExtension, nil, GetFileNameCallBack);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FExterStoragePath: string = '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FInnerStoragePath: string = '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FVolumePaths: string = '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FSDRegisteredReceiver: Boolean = False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//type
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TSDBroadcastListener = class(TJavaLocal, JFMXBroadcastReceiverListener)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  private
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    //[Weak] FTestObj: TForm1;  //TForm1 是拿来测试,不是必须的。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  public
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    constructor Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    //看上去,下面的函数属于线程中
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    procedure onReceive(context: JContext; intent: JIntent); cdecl;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  //安卓下消息3元素。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDBroadcastReceiver: JFMXBroadcastReceiver;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter: JIntentFilter;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDBroadcastListener: TSDBroadcastListener;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  //你的 APP 安卓对象。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FActivity: JNativeActivity;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{ TSDBroadcastListener }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//constructor TSDBroadcastListener.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  inherited Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  InnerStoragePath := GetSDCardPath(0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExterStoragePath := GetSDCardPath(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExterStoragePathCanRead := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExterStoragePathCanWrite := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  SDMountedMessageReceived := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//procedure TSDBroadcastListener.onReceive(context: JContext; intent: JIntent);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Action,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExternalPath,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempStr1, TempStr2, TempStr3,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempStr: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AJFile: JFile;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  //这里就是处理消息的地方。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Action := JStringToString(intent.getAction);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempStr1 := JStringToString(TJIntent.JavaClass.ACTION_MEDIA_MOUNTED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempStr2 := JStringToString(TJIntent.JavaClass.ACTION_MEDIA_UNMOUNTED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExternalPath := IncludeTrailingPathDelimiter(GetExternalStoragePath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if SameText(Action, TempStr1) or SameText(Action, TempStr2) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    TempStr := JStringToString(intent.getData.getPath);// 外置设备路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    TempStr := IncludeTrailingPathDelimiter(TempStr);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    if TOSVersion.Check(5) and SameFileName(TempStr, ExternalPath) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      //说明内外卡交换了。这是 5.0 的特点。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      InnerStoragePath := ExterStoragePath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      ExterStoragePath := TempStr;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    if SameFileName(TempStr, ExterStoragePath) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      if SameText(Action, TempStr1) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        ExterStoragePathCanRead := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        AJFile := TJFile.JavaClass.init(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//          StringToJString(ExcludeTrailingPathDelimiter(TempStr)));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        if AJFile <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//          ExterStoragePathCanRead := AJFile.canRead;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//          ExterStoragePathCanWrite := AJFile.canWrite;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        SDMountedMessageReceived := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempStr1 := JStringToString(TJIntent.JavaClass.ACTION_MEDIA_REMOVED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempStr2 := JStringToString(TJIntent.JavaClass.ACTION_MEDIA_SHARED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempStr3 := JStringToString(TJIntent.JavaClass.ACTION_MEDIA_EJECT);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if SameText(Action, TempStr1) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    SameText(Action, TempStr2) or SameText(Action, TempStr3) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    TempStr := JStringToString(intent.getData.getPath);// 外置设备路径
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    TempStr := IncludeTrailingPathDelimiter(TempStr);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    if SameFileName(TempStr, ExterStoragePath) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      ExterStoragePathCanRead := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      ExterStoragePathCanWrite := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//procedure RegisterSDReceiver;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if FSDRegisteredReceiver then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FActivity := TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  //FActivity :=
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{$IF CompilerVersion >= 30.0} // >=RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    TAndroidHelper.Activity
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    SharedActivity
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{$ENDIF};
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDBroadcastListener := TSDBroadcastListener.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDBroadcastReceiver := TJFMXBroadcastReceiver.JavaClass.init(FSDBroadcastListener);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  //http://blog.csdn.net/yigelangmandeshiren/article/details/8145059
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter := TJIntentFilter.JavaClass.init(TJIntent.JavaClass.ACTION_MEDIA_MOUNTED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter.setPriority(1000);// 设置最高优先级
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter.addAction(TJIntent.JavaClass.ACTION_MEDIA_EJECT);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter.addAction(TJIntent.JavaClass.ACTION_MEDIA_REMOVED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter.addAction(TJIntent.JavaClass.ACTION_MEDIA_SHARED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter.addAction(TJIntent.JavaClass.ACTION_MEDIA_UNMOUNTED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter.addDataScheme(StringToJString('file'));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  //注册消息接收器。别忘了 unregisterReceiver(FBroadcastReceiver);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FActivity.registerReceiver(FSDBroadcastReceiver, FSDIntentFilter);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//procedure UnRegisterSDReceiver;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if not FSDRegisteredReceiver then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FActivity.unregisterReceiver(FSDBroadcastReceiver);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FreeAndNil(FSDBroadcastListener);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDBroadcastReceiver := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FSDIntentFilter := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  FActivity := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetIsExternalStorageRemovable: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := TJEnvironment.JavaClass.isExternalStorageRemovable;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //低版本可能发生错误。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetExterStoragePath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AJstr: JString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FExterStoragePath.Trim = '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FExterStoragePath := GetSDCardPath(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if GetIsExternalStorageRemovable then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FExterStoragePath := GetSDCardPath(0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := FExterStoragePath.Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not DirectoryExists(ExcludeTrailingPathDelimiter(Result)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AJstr := TJSystem.JavaClass.getenv(StringToJString('SECONDARY_STORAGE'));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if AJstr <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := IncludeTrailingPathDelimiter(JStringToString(AJstr));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetInnerStoragePath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AJstr: JString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FInnerStoragePath.Trim = '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FInnerStoragePath := GetSDCardPath(0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if GetIsExternalStorageRemovable then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FInnerStoragePath := GetSDCardPath(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := FInnerStoragePath.Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not DirectoryExists(ExcludeTrailingPathDelimiter(Result)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ExterStoragePath := GetSDCardPath(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AJstr := TJSystem.JavaClass.getenv(StringToJString('EXTERNAL_STORAGE'));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if AJstr <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := IncludeTrailingPathDelimiter(JStringToString(AJstr));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetVolumePaths: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Sm: JStorageManager;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SmNative: JObject;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AList: TStrings;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  VolumePaths: TJavaObjectArray<JString>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  I: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not IsCanFindJavaMethod('getVolumePaths',
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '()[Ljava/lang/String;', 'android/os/storage/StorageManager') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //可以返回点别的。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Sm := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SmNative :=
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion >= 30.0} // >=RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TAndroidHelper.Context
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SharedActivityContext
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .getSystemService(TJContext.JavaClass.STORAGE_SERVICE);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if SmNative <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Sm := TJStorageManager.Wrap((SmNative as ILocalObject).GetObjectID);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //不打算兼容 2.X 了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (Sm <> nil) and TOSVersion.Check(4) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AList := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        VolumePaths := Sm.getVolumePaths;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for I := 0 to VolumePaths.Length - 1 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          AList.Add(JStringToString(VolumePaths.Items[I]));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      VolumePaths := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := AList.Text;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FVolumePaths := Result;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FreeAndNil(AList);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//function GetActiveMemorySize: UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AStringVs,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AStrings: TStringList;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TempValue: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ABufferedReader: JBufferedReader;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  V1, V2: UInt64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if FileExists('/proc/meminfo') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    AStrings := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    AStringVs := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStrings.LineBreak := sLineBreak;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStrings.NameValueSeparator := ':';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStrings.Clear;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      ABufferedReader := TJBufferedReader.JavaClass.init(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        JReader(TJFileReader.JavaClass.init(StringToJString('/proc/meminfo'))));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      repeat
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        TempValue := JStringToString(ABufferedReader.readLine);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        if TempValue <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//          AStrings.Add(TempValue);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      until (not ABufferedReader.ready);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      ABufferedReader.close;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      V1 := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      TempValue := AStrings.Values['Mapped'].Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStringVs.Clear;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStringVs.NameValueSeparator := ' ';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStringVs.Add(TempValue.Trim);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      TempValue := AStringVs.Names[0];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      V2 := StrToInt64Def(TempValue, 0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      V1 := V1 + V2;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      TempValue := AStrings.Values['Inactive'].Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStringVs.Clear;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStringVs.NameValueSeparator := ' ';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      AStringVs.Add(TempValue.Trim);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      TempValue := AStringVs.Names[0];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      V2 := StrToInt64Def(TempValue, 0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      V1 := V1 + V2;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      Result := V1 * 1024;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      FreeAndNil(AStringVs);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      FreeAndNil(AStrings);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if Result = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := GetFreeMemorySize;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetScreenClientInches: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  x,y: Double;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  dm: JDisplayMetrics;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 3;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  dm := GetJDisplayMetrics;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if dm = nil then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  x := dm.widthPixels;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  y := dm.heightPixels;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  x := System.Math.Power(x / dm.xdpi, 2);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  y := System.Math.Power(y / dm.ydpi, 2);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := Sqrt(x + y);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (dm.densityDpi > dm.xdpi) and (dm.densityDpi > dm.ydpi) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := Sqrt(x * x + y * y ) / dm.densityDpi;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := Sqrt((x * x / dm.xdpi / dm.xdpi) + (y * y / dm.ydpi / dm.ydpi));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsCanFindJavaClass(const NamePath: string): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv: PJNIEnv;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PActivity: PANativeActivity;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ContextClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AMS: MarshaledAString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TempClass := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PActivity := PANativeActivity(System.DelphiActivity);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PActivity^.vm^.AttachCurrentThread(PActivity^.vm, @PEnv, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PJavaVM(System.JavaMachine)^.AttachCurrentThread(System.JavaMachine, @PEnv, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ContextClass := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ContextClass := PEnv^.GetObjectClass(PEnv, System.JavaContext);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AMS := MarshaledAString(Utf8Encode(NamePath.Trim.Replace('.', '/', [rfReplaceAll])));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TempClass := PEnv^.FindClass(PEnv, AMS);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PEnv^.ExceptionClear(PEnv);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := TempClass <> nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if TempClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.DeleteLocalRef(PEnv, TempClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ContextClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.DeleteLocalRef(PEnv, ContextClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsCanFindJavaMethod(const MethodName, Signature: string; const CalssNamePath: string = ''): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv: PJNIEnv;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PActivity: PANativeActivity;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ContextClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ActivityClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetMethod: JNIMethodID;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ASignature: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AMSMethodName, AMSSignature: MarshaledAString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AMSMethodName := MarshaledAString(Utf8Encode(MethodName.Trim));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PActivity := PANativeActivity(System.DelphiActivity);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PActivity^.vm^.AttachCurrentThread(PActivity^.vm, @PEnv, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PJavaVM(System.JavaMachine)^.AttachCurrentThread(System.JavaMachine, @PEnv, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ContextClass := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ContextClass := PEnv^.GetObjectClass(PEnv, System.JavaContext);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ActivityClass := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if CalssNamePath.Trim <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ASignature := CalssNamePath.Trim.Replace('.', '/', [rfReplaceAll]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AMSSignature := MarshaledAString(Utf8Encode(ASignature));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ActivityClass := PEnv^.FindClass(PEnv, AMSSignature);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.ExceptionClear(PEnv);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ActivityClass := PEnv^.GetObjectClass(PEnv, PActivity^.clazz);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ActivityClass := PEnv^.GetObjectClass(PEnv, System.JavaContext);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ActivityClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ASignature := Signature.Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AMSSignature := MarshaledAString(Utf8Encode(ASignature));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        GetMethod := PEnv^.GetMethodID(PEnv, ActivityClass, AMSMethodName, AMSSignature);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.ExceptionClear(PEnv);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := GetMethod <> nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ActivityClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.DeleteLocalRef(PEnv, ActivityClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ContextClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.DeleteLocalRef(PEnv, ContextClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function IsCanFindJavaStaticMethod(const MethodName, Signature: string; const CalssNamePath: string = ''): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv: PJNIEnv;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PActivity: PANativeActivity;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ContextClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ActivityClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetMethod: JNIMethodID;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ASignature: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AMSMethodName, AMSSignature: MarshaledAString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AMSMethodName := MarshaledAString(Utf8Encode(MethodName.Trim));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PActivity := PANativeActivity(System.DelphiActivity);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PActivity^.vm^.AttachCurrentThread(PActivity^.vm, @PEnv, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PJavaVM(System.JavaMachine)^.AttachCurrentThread(System.JavaMachine, @PEnv, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ContextClass := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ContextClass := PEnv^.GetObjectClass(PEnv, System.JavaContext);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ActivityClass := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if CalssNamePath.Trim <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ASignature := CalssNamePath.Trim.Replace('.', '/', [rfReplaceAll]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AMSSignature := MarshaledAString(Utf8Encode(ASignature));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ActivityClass := PEnv^.FindClass(PEnv, AMSSignature);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.ExceptionClear(PEnv);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ActivityClass := PEnv^.GetObjectClass(PEnv, PActivity^.clazz);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ActivityClass := PEnv^.GetObjectClass(PEnv, System.JavaContext);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ActivityClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ASignature := Signature.Trim;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AMSSignature := MarshaledAString(Utf8Encode(ASignature));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        GetMethod := PEnv^.GetStaticMethodID(PEnv, ActivityClass, AMSMethodName, AMSSignature);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.ExceptionClear(PEnv);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := GetMethod <> nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ActivityClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.DeleteLocalRef(PEnv, ActivityClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF CompilerVersion < 30.0} // < RAD10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ContextClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PEnv^.DeleteLocalRef(PEnv, ContextClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+procedure UpdateAlbum(FileNames: string);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AJStrList:  TJavaObjectArray<JString>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  I: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  With TStringList.Create do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Text := FileNames;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AJStrList := TJavaObjectArray<JString>.Create(Count);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for I := 0 to Count - 1 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AJStrList.Items[I] := StringToJString(Strings[I]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TJMediaScannerConnection.JavaClass.scanFile(TAndroidHelper.Context, AJStrList,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nil, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function ReadFileToString(const AFileName: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AReader: JReader;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ABufferedReader: JBufferedReader;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempValue: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not FileExists(AFileName) then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AReader := TJFileReader.JavaClass.init(StringToJString(AFileName)) as JReader;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ABufferedReader := TJBufferedReader.JavaClass.init(AReader);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  repeat
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TempValue := JStringToString(ABufferedReader.readLine);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if TempValue <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := Result + sLineBreak + TempValue;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  until (not ABufferedReader.ready);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ABufferedReader.close;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function ReadNoSizeFileToString(const AFileName: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not FileExists(AFileName) then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  With TFileStream.Create(AFileName, fmOpenRead) do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Size = -1 then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := ReadFileToString(AFileName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetJniPath(MethodName, Signature: MarshaledAString): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv: PJniEnv;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ActivityClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileClass: JNIClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetMethod: JNIMethodID;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetPathMethod: JNIMethodID;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PActivity: PANativeActivity;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  StrPathObject: JNIObject;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileObject: JNIObject;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PActivity := PANativeActivity(System.DelphiActivity);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PActivity^.vm^.AttachCurrentThread(PActivity^.vm, @PEnv, nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ActivityClass := PEnv^.GetObjectClass(PEnv, PActivity^.clazz);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetMethod := PEnv^.GetMethodID(PEnv, ActivityClass, MethodName, Signature);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileObject := PEnv^.CallObjectMethodA(PEnv, PActivity^.clazz, GetMethod, PJNIValue(ArgsToJNIValues([nil])));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileObject = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit('');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileClass := PEnv^.GetObjectClass(PEnv, FileObject);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetPathMethod := PEnv^.GetMethodID(PEnv, FileClass, 'getPath', '()Ljava/lang/String;');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  StrPathObject := PEnv^.CallObjectMethodA(PEnv, FileObject, GetPathMethod, PJNIValue(ArgsToJNIValues([])));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := JNIStringToString(PEnv, StrPathObject);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv^.DeleteLocalRef(PEnv, StrPathObject);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv^.DeleteLocalRef(PEnv, FileClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv^.DeleteLocalRef(PEnv, FileObject);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PEnv^.DeleteLocalRef(PEnv, ActivityClass);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function JNIgetExternalStorageDirectory(SubPath: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if SubPath <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := IncludeTrailingPathDelimiter(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      GetJniPath('getExternalStorageDirectory', '()Landroid/os/Environment;')
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      ) + SubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := GetJniPath('getExternalStorageDirectory', '()Landroid/os/Environment;');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if SubPath <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := IncludeTrailingPathDelimiter(JStringToString(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        TJEnvironment.JavaClass.getExternalStorageDirectory.getPath)) + SubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := JStringToString(TJEnvironment.JavaClass.getExternalStorageDirectory.getPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //低版本可能发生错误。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetExternalStoragePath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := IncludeTrailingPathDelimiter(JNIgetExternalStorageDirectory(''));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//function isPathCanWrite(const PathOrDir: string; const Default: Boolean = True): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ADir: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ADir := ExcludeTrailingPathDelimiter(PathOrDir);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if not DirectoryExists(ADir) then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+////明明无权限写入,却返回 canWrite 为 True
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    if not TJFile.JavaClass.init(StringToJString(ADir)).canWrite then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function isPathCanUseNow(const PathOrDir: string; const Default: Boolean = True): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ADir: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ADir := ExcludeTrailingPathDelimiter(PathOrDir);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not DirectoryExists(ADir) then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    //下面的代码不能正确的区分内外 SD。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := TJEnvironment.JavaClass.getExternalStorageState.equals(TJEnvironment.JavaClass.MEDIA_MOUNTED);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    if GetExterStoragePath.Trim = '' then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    if FindJavaMethod('getStorageState',
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      '(Ljava/io/File;)Ljava/lang/String;', 'android/os/Environment') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      // 这个接口 5.0 会死锁。还是不用了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      if not TJEnvironment.JavaClass.getStorageState(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        TJFile.JavaClass.init(StringToJString(ADir))).equals(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//          TJEnvironment.JavaClass.MEDIA_MOUNTED) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not TJFile.JavaClass.init(StringToJString(ADir)).canRead then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function isPathCanUseNow(const PathOrDir: string; const Default: Boolean = True): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not DirectoryExists(ExcludeTrailingPathDelimiter(PathOrDir)) then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := Default;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function TestPathCanWrite(const PathOrDir: string): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ATempFile,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ADir: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AHandle: THandle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ADir := ExcludeTrailingPathDelimiter(PathOrDir);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not DirectoryExists(ADir) then exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  repeat
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ATempFile := System.IOUtils.TPath.GetTempFileName;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if FileExists(ATempFile) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.IOUtils.TFile.Delete(ATempFile);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ATempFile := IncludeTrailingPathDelimiter(ADir) + ExtractFileName(ATempFile);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  until not FileExists(ATempFile);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ATempFile := GetTempFileName(ADir);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if FileExists(ATempFile) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    System.IOUtils.TFile.Delete(ATempFile);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AHandle := INVALID_HANDLE_VALUE;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF Defined(MSWINDOWS)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AHandle := FileCreate(ATempFile, 0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSEIF Defined(POSIX)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AHandle := FileCreate(ATempFile, FileAccessRights);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if AHandle = INVALID_HANDLE_VALUE then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FileClose(AHandle);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileExists(ATempFile) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    System.IOUtils.TFile.Delete(ATempFile);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//function GetTempFileName(const ATempPath: string): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ErrCode: UINT;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  SetLength(Result, MAX_PATH);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  SetLastError(ERROR_SUCCESS);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  ErrCode := Winapi.Windows.GetTempFileName(PChar(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    IncludeTrailingPathDelimiter(ATempPath)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    ), 'tmp', 0, PChar(Result)); // DO NOT LOCALIZE
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if ErrCode = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    raise EInOutError.Create(SysErrorMessage(GetLastError));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  SetLength(Result, StrLen(PChar(Result)));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if FileExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    System.IOUtils.TFile.Delete(Result);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{$IFDEF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  LTempPath: TBytes;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  M: TMarshaller;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  LRet: MarshaledAString;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+////   char * tempnam(const char *dir, const char *pfx);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  { Obtain a temporary file name }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  // This code changed from getting the temp name from the temp path via system
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  // to get the temp name inside the specified temp path. We get the system temp path.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+////  LTempPath := TEncoding.UTF8.GetBytes(string(tmpnam(nil)));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  LRet := tempnam(MarshaledAString(M.AsUTF8(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// //返回的路径没有包含 ATempPath
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    IncludeTrailingPathDelimiter(ATempPath)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    ).ToPointer),nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  LTempPath := TEncoding.UTF8.GetBytes(string(LRet));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  free(LRet);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  { Convert to UTF16 or leave blank on possible error }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  if LTempPath <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := TEncoding.UTF8.GetString(LTempPath)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//{$ENDIF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function FileSystemAttributes(const Path: string): TFileSystemAttributes;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := [fsSymLink, fsCaseSensitive];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  For android platform we can use the function PathConf on the same way
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  that is used on IOS, but the problem is that for android we only can check
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  _PC_2_SYMLINKS name, and that call is failing on version 2.3.3.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function ExpandFileNameCase2(const FileName, RootPath: string; out MatchFound: TFilenameCaseMatch): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SR: System.SysUtils.TSearchRec;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FullPath, Name: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Status: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FoundOne: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Scans: Byte;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FirstLetter, TestLetter: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := ExpandFileName(FileName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MatchFound := mkNone;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FileName = '' then // Stop for empty strings, otherwise we risk to get info infinite loop.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FullPath := ExtractFilePath(Result);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Name := ExtractFileName(Result);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // if FullPath is not the root directory  (portable)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not SameFileName(FullPath, IncludeTrailingPathDelimiter(ExtractFileDrive(FullPath))) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin  // Does the path need case-sensitive work?
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Status := FindFirst(ExcludeTrailingPathDelimiter(FullPath), faAnyFile, SR);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    System.SysUtils.FindClose(SR);   // close search before going recursive
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Status <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if SameFileName(IncludeTrailingPathDelimiter(FullPath), IncludeTrailingPathDelimiter(RootPath)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FullPath := ExcludeTrailingPathDelimiter(FullPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FullPath := ExpandFileNameCase2(FullPath, RootPath, MatchFound);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if MatchFound = mkNone then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Exit;    // if we can't find the path, we certainly can't find the file!
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FullPath := IncludeTrailingPathDelimiter(FullPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Path is validated / adjusted.  Now for the file itself
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if System.SysUtils.FindFirst(FullPath + Name, faAnyFile, SR)= 0 then    // exact match on filename
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not (MatchFound in [mkSingleMatch, mkAmbiguous]) then  // path might have been inexact
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if Name = SR.Name then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          MatchFound := mkExactMatch
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          MatchFound := mkSingleMatch;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Exit(FullPath + SR.Name);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    System.SysUtils.FindClose(SR);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ Scan the directory.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  To minimize the number of filenames tested, scan the directory
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  using upper/lowercase first letter + wildcard.
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  This results in two scans of the directory (particularly on Linux) but
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  vastly reduces the number of times we have to perform an expensive
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  locale-charset case-insensitive string compare.  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FoundOne := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (fsCaseSensitive in FileSystemAttributes(FullPath)) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     (fsCasePreserving in FileSystemAttributes(FullPath)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // First, scan for lowercase first letter
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FirstLetter := AnsiLowerCase(Name[Low(string)]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for Scans := 0 to 1 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Status := FindFirst(FullPath + FirstLetter + '*', faAnyFile, SR);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while Status = 0 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if AnsiSameText(SR.Name, Name) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if FoundOne then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin  // this is the second match
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            MatchFound := mkAmbiguous;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FoundOne := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := FullPath + SR.Name;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Status := FindNext(SR);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FindClose(SR);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TestLetter := AnsiUpperCase(Name[Low(string)]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if TestLetter = FirstLetter then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FirstLetter := TestLetter;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if MatchFound <> mkAmbiguous then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if FoundOne then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        MatchFound := mkSingleMatch
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        MatchFound := mkNone;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function BuildFileListInAPath(const Path: string; const Attr: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  JustFile: Boolean = False): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AList: TStringList;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AList := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BuildFileListInAPath(Path, Attr, AList, JustFile);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := AList.Text;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FreeAndNil(AList);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function BuildFileListInAPath(const Path: string; const Attr: Integer; const List: TStrings;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  JustFile: Boolean = False): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SearchRec: TSearchRec;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  R: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Assert(List <> nil);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  R := System.SysUtils.FindFirst(ExcludeTrailingPathDelimiter(Path), Attr, SearchRec);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := R = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Result then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while R = 0 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if ((SearchRec.Attr and faDirectory) = faDirectory) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if not JustFile then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              List.Add(SearchRec.Name);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List.Add(SearchRec.Name);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        R := System.SysUtils.FindNext(SearchRec);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := R = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    System.SysUtils.FindClose(SearchRec);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function faAttrToFileAttributes(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Attributes: Integer): TFileAttributes;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := [];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faReadOnly <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faReadOnly);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faHidden <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faHidden);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faSysFile <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faSystem);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faDirectory <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faDirectory);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faArchive <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faArchive);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faSymLink <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faSymLink);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faNormal <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faNormal);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faTemporary <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faTemporary);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faCompressed <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faCompressed);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faEncrypted <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faEncrypted);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := [];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faDirectory <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faDirectory);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faArchive <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faNormal);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faSymLink <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faSymLink);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Attributes and faNormal <> 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Include(Result, TFileAttribute.faNormal);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF POSIX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//好像不一定有效果。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function FileSetAttr(const FileName: string; Attr: Integer; FollowLink: Boolean = True): Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AFileAttributes: TFileAttributes;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Result := faInvalid;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  AFileAttributes := faAttrToFileAttributes(Attr);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  TFile.SetAttributes(FileName, AFileAttributes);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function DeleteTreeByEcho(const Source: string; AbortOnFailure: Boolean = False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  YesToAll: Boolean = True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WaitMinSecond: Integer = DeleteDirectories_WaitMinSecond): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Files: TStringList;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  LPath: string; // writable copy of Path
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FileName: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  I: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PartialResult: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Attr: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  isDir: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ToDeleteDir: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  T: TDateTime;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FWaitSecond, FWaitMinSecond: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not DirectoryExists(ExtractFileDir(Source)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Trim(Source) = PathDelim then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  isDir := DirectoryExists(Source);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Files := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if isDir then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      LPath := IncludeTrailingPathDelimiter(Source);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ToDeleteDir := LPath + '\*.*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      LPath := IncludeTrailingPathDelimiter(ExtractFilePath(Source));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ToDeleteDir := Source;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BuildFileListInAPath(ToDeleteDir, faAnyFile, Files);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for I := 0 to Files.Count - 1 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FileName := LPath + PathDelim + Files[I];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      PartialResult := True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // If the current file is itself a directory then recursively delete it
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Attr := FileGetAttr(FileName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (Attr <> faInvalid) and ((Attr and faDirectory) <> 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PartialResult := DeleteTreeByEcho(FileName, AbortOnFailure, YesToAll,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WaitMinSecond);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if YesToAll then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Set attributes to normal in case it's a readonly file
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          PartialResult := FileSetAttr(FileName, faNormal) = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if ((Attr and faSysFile) <> 0) or ((Attr and faReadOnly) <> 0) or (Attr = faInvalid)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PartialResult := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if PartialResult then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          PartialResult := System.SysUtils.DeleteFile(FileName); //TFile.Delete()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not PartialResult then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if AbortOnFailure then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FreeAndNil(Files);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Result and isDir then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if YesToAll then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Finally remove the directory itself
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := FileSetAttr(LPath, faNormal or faDirectory) = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Attr := FileGetAttr(LPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ((Attr and faSysFile) <> 0) or ((Attr and faReadOnly) <> 0) or (Attr = faInvalid) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Result then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IOCHECKS OFF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      RmDir(LPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      T := Now;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FWaitSecond := WaitMinSecond div 1000;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      FWaitMinSecond := WaitMinSecond mod 1000;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while DirectoryExists(LPath) do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if T + EncodeTime(0, 0, FWaitSecond, FWaitMinSecond) < now then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Sleep(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF IOCHECKS_ON}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IOCHECKS ON}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF IOCHECKS_ON}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Result := IOResult = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := not DirectoryExists(LPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // if not Result then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // ShowMessage(LPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function DeleteDirectoryByEcho(const Source: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AbortOnFailure: Boolean = False; YesToAll: Boolean = True;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WaitMinSecond: Integer = DeleteDirectories_WaitMinSecond): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  T: TDateTime;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FWaitSecond, FWaitMinSecond: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if not DirectoryExists(ExtractFileDir(Source)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Trim(Source) = PathDelim then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := DeleteTreeByEcho(Source, AbortOnFailure, YesToAll, WaitMinSecond);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Result then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    T := Now;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FWaitSecond := WaitMinSecond div 1000;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FWaitMinSecond := WaitMinSecond mod 1000;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while DirectoryExists(Source) do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if T + EncodeTime(0, 0, FWaitSecond, FWaitMinSecond) < now then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Sleep(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetFileNamesFromDirectory(const DirName: string; const SearchFilter: string = '*';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const FileAttribs: Integer = faAnyFile; const isIncludeSubDirName: Boolean = False; const Recursion: Boolean = False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const FullName: Boolean = False): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SubList, FileNameList: TStrings;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DirPath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SearchRec: TSearchRec;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  i: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Trim(SearchFilter) = '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DirectoryExists(DirName) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FileNameList := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DirPath := IncludeTrailingPathDelimiter(DirName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 得到该目录下指定类型文件的文件名
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if System.SysUtils.FindFirst(DirPath + Trim(SearchFilter), FileAttribs, SearchRec) = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          repeat
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if isIncludeSubDirName or ((SearchRec.Attr and faDirectory) <> faDirectory) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (SearchRec.Attr and faDirectory) = faDirectory then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (ExtractFileName(SearchRec.Name) = '.') or (ExtractFileName(SearchRec.Name) = '..') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  Continue;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if FullName then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FileNameList.Add(ExpandFileName(SearchRec.Name));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FileNameList.Add(ExtractFileName(SearchRec.Name));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          until System.SysUtils.FindNext(SearchRec) <> 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          System.SysUtils.FindClose(SearchRec);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 递归该目录下所有子目录下的指定文件。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if Recursion and (System.SysUtils.FindFirst(DirPath + '*', faDirectory, SearchRec) = 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          repeat
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if Recursion and ((SearchRec.Attr and faDirectory) = faDirectory) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              Result := GetFileNamesFromDirectory(DirPath + ExtractFileName(SearchRec.Name), SearchFilter,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FileAttribs, isIncludeSubDirName, Recursion, FullName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              SubList := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SubList.Clear;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SubList.Text := Result;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if not FullName then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  for i := 0 to SubList.Count - 1 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    SubList.Strings[i] := ExtractFileName(SearchRec.Name) + PathDelim + SubList.Strings[i];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FileNameList.AddStrings(SubList);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FreeAndNil(SubList);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          until System.SysUtils.FindNext(SearchRec) <> 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          System.SysUtils.FindClose(SearchRec);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := FileNameList.Text;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      except
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if FileNameList <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FreeAndNil(FileNameList);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetCaseSensitiveFileName(const FileName: string; RootPath: string = ''): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MatchFound: TFilenameCaseMatch;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := ExpandFileNameCase2(FileName, RootPath, MatchFound);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetSDCardPath(Index: Integer = 0): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := FindSDCardSubPath('', Index);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function FindSDCardSubPath(SubPath: string; Index: Integer = 0): string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PathDelimedSubPath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UnPathDelimedSubPath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  VolumePathList: TStrings;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UsbIndex,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CdRomIndex,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempVolumeIndex,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  I: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IsFoundDir0: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PathDelimedSubPath := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UnPathDelimedSubPath := SubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if UnPathDelimedSubPath <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if UnPathDelimedSubPath.Chars[0] = PathDelim then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      UnPathDelimedSubPath := UnPathDelimedSubPath.Substring(1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PathDelimedSubPath := PathDelim + UnPathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := '/storage/emulated/' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if FVolumePaths.Trim = '' then GetVolumePaths;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  VolumePathList := TStringList.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    VolumePathList.Text := FVolumePaths;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Index = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := JNIgetExternalStorageDirectory(UnPathDelimedSubPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) and (VolumePathList.Count > 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := VolumePathList[0];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/emulated/' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard_ext0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard_ext' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/sdcard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard_ext0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard_ext' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/emmc' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/nand' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/flash' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/emmc' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/flash' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/flash' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/D' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/D' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/flash' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/flash' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //last
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if (Index < UsbDiskStartIndex) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard' + IntToStr(Index + 1) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := 'sdcard' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := 'sdcard' + IntToStr(Index + 1) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard_ext' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard_ext' + IntToStr(Index + 1) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard' + IntToStr(Index + 1) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard_ext' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/mnt/sdcard_ext' + IntToStr(Index + 1) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) and (VolumePathList.Count > Index) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := VolumePathList[Index];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Result.IndexOf('usbcd') >= 0) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (Result.IndexOf('usb') >= 0) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (Result.IndexOf('otg') >= 0) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (Result.IndexOf('-rw') >= 0) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (Result.IndexOf('_rw') >= 0) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (Result.IndexOf('cdrom') >= 0) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (Result.IndexOf('cd_rom') >= 0) or
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (Result.IndexOf('cd-rom') >= 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if Index = 1 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) and (VolumePathList.Count = 2) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := VolumePathList[1];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (Result.IndexOf('/storage/emulated/') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (Result.IndexOf('/storage/sdcard') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (Result.IndexOf('/mnt/sdcard') < 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/extSdCard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/external1' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/sdcard-ext' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/ext_card' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/extsd' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/_ExternalSD' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/external_sd' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/removable_sdcard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/extSdCard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/external1' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/sdcard-ext' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/ext_card' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/extsd' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/_ExternalSD' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/external_sd' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/mnt/removable_sdcard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := 'tflash' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := 'removable_sdcard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'tflash' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'extSdCard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'external1' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'sdcard-ext' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'ext_card' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'extsd' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + '_ExternalSD' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'external_sd' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(0) + 'removable_sdcard' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //last
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := '/storage/sdcard' + IntToStr(Index) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if (Index >= UsbDiskStartIndex) and (Index < UsbDiskStartIndex + OTGDeivceCount) then  //UsbDiskStartIndex
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      UsbIndex := Index - UsbDiskStartIndex;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TempVolumeIndex := UsbIndex;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for I := 1 to VolumePathList.Count - 1 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := ExcludeTrailingPathDelimiter(VolumePathList[I]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Result.IndexOf('/storage/usb') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (Result.IndexOf('/storage/otg') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (Result.IndexOf('/mnt/otg') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (Result.IndexOf('/mnt/usb') < 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else if DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (Result.IndexOf('usbcd') >= 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else if (Result.IndexOf('otgcd') >= 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else if (TempVolumeIndex = 0) and (Result.Chars[Result.Length] in ['2'..'9']) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else if (TempVolumeIndex <> 0) and (Result.Chars[Result.Length] <> IntToStr(TempVolumeIndex)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := Result + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (Result = '') or (not DirectoryExists(Result)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if UsbIndex = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/udisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/udisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'udisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbdisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbdisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbdisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbotg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbotg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbotg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbdrive' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbdrive' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbdrive' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usb' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usb' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usb' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/otg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/otg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'otg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'udisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usbotg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usb' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'otg' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //index = 0
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/udisk0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/udisk0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'udisk0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbdisk0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbdisk0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbdisk0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbotg0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbotg0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbotg0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbdrive0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbdrive0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbdrive0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usb0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usb0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usb0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'udisk0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usbotg0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usb0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //index > 0
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          IsFoundDir0 := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(UsbDiskStartIndex);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          IsFoundDir0 := Result.Chars[Result.Length] = '0';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not IsFoundDir0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            inc(TempVolumeIndex);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/udisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/udisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'udisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbdisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbdisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbdisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbotg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbotg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbotg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbdrive' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbdrive' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbdrive' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usb' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usb' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usb' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/otg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/otg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'otg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'udisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usbotg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usb' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'otg' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //last
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (Result = '') or (not DirectoryExists(Result)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if UsbIndex = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/udisk' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/udisk' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if (Index >= CDROMStartIndex) and (Index < CDROMStartIndex + OTGDeivceCount) then  //CDROMStartIndex
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      CdRomIndex := Index - CDROMStartIndex;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TempVolumeIndex := CdRomIndex;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for I := 1 to VolumePathList.Count - 1 do
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Result := ExcludeTrailingPathDelimiter(VolumePathList[I]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Result.IndexOf('/storage/cd') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (Result.IndexOf('/mnt/cd') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (Result.IndexOf('/storage/usbcd') < 0) and
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (Result.IndexOf('/mnt/usbcd') < 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else if DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (TempVolumeIndex = 0) and (Result.Chars[Result.Length] in ['2'..'9']) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else if (TempVolumeIndex <> 0) and (Result.Chars[Result.Length] <> IntToStr(TempVolumeIndex)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := Result + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (Result = '') or (not DirectoryExists(Result)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if CdRomIndex = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/media_rw' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/media_rw' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'media_rw' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/cd_rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cd_rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cd_rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbcdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbcdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbcdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/cdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usbcdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'cdrom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //index = 0
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/cd_rom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cd_rom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cd_rom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbcdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbcdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbcdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/cdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'cd-rom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usbcdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'cdrom0' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //index > 0
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          IsFoundDir0 := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := GetSDCardPath(CDROMStartIndex);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          IsFoundDir0 := Result.Chars[Result.Length] = '0';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not IsFoundDir0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            inc(TempVolumeIndex);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/cd_rom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cd_rom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cd_rom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/usbcdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/usbcdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'usbcdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/storage/cdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := '/mnt/cdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := 'cdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'cd-rom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'usbcdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not DirectoryExists(Result) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := GetSDCardPath(0) + 'cdrom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //last
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (Result = '') or (not DirectoryExists(Result)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if CdRomIndex = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/cd-rom' + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := '/storage/cd-rom' + IntToStr(TempVolumeIndex) + PathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := JNIgetExternalStorageDirectory(UnPathDelimedSubPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FreeAndNil(VolumePathList);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if UnPathDelimedSubPath <> '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := IncludeTrailingPathDelimiter(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      System.IOUtils.TPath.GetSharedDocumentsPath) + UnPathDelimedSubPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := System.IOUtils.TPath.GetSharedDocumentsPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := IncludeTrailingPathDelimiter(Result);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function GetAppPath: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$IF Defined(ANDROID)}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := ExtractFilePath(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ExcludeTrailingPathDelimiter(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    System.IOUtils.TPath.GetHomePath));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := ExtractFilePath(ParamStr(0));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$ENDIF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := IncludeTrailingPathDelimiter(Result);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//initialization
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//finalization
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  UnRegisterSDReceiver;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end.
 
			 |