123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600 |
- 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.
|