package Ġcom . ang gray udi . storage . media Ċ Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . annotation . Target Api Ċ import Ġandroid . app . Recover able Security Exception Ċ import Ġandroid . content . Content Values Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . Intent Sender Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Build Ċ import Ġandroid . provider . Media Store Ċ import Ġandroid . text . format . Formatter Ċ import Ġandroidx . annotation . Requires Api Ċ import Ġandroidx . annotation . Ui Thread Ċ import Ġandroidx . annotation . Worker Thread Ċ import Ġandroidx . core . content . File Provider Ċ import Ġandroidx . document file . provider . Document File Ċ import Ġcom . ang gray udi . storage . Simple Storage Ċ import Ġcom . ang gray udi . storage . callback . File Callback Ċ import Ġcom . ang gray udi . storage . extension .* Ċ import Ġcom . ang gray udi . storage . file .* Ċ import Ġcom . ang gray udi . storage . file . Document File Compat . remove Forbidden Chars From Filename Ċ import Ġkotlinx . coroutines . Job Ċ import Ġjava . io .* Ċ Ċ /** Ċ Ġ* ĠCreated Ġon Ġ 0 6 / 0 9 / 2 0 Ċ Ġ* Ġ@ author ĠAng gray udi ĠH Ċ Ġ*/ Ċ @ Suppress (" DE PREC ATION ") Ċ class ĠMedia File ( context : ĠContext , Ġval Ġuri : ĠUri ) Ġ{ ĊĊĠĠĠ Ġconstructor ( context : ĠContext , Ġraw File : ĠFile ) Ġ: Ġthis ( context , ĠUri . from File ( raw File )) ĊĊĠĠĠ Ġprivate Ġval Ġcontext Ġ= Ġcontext . application Context ĊĊĠĠĠ Ġinterface ĠAccess Callback Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWhen Ġthis Ġfunction Ġcalled , Ġyou Ġcan Ġask Ġuser 's Ġconcent Ġto Ġmodify Ġother Ġapp 's Ġfiles . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ see ĠRe cover able Security Exception ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ see Ġ[ android . app . Activity . start Intent Sender For Result ] ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġon Write Access Denied ( media File : ĠMedia File , Ġsender : ĠIntent Sender ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOnly Ġuseful Ġfor ĠAndroid Ġ 1 0 Ġand Ġhigher . ĊĠĠĠĠ Ġ* Ġ@ see ĠRe cover able Security Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġaccess Callback : ĠAccess Callback ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSome Ġmedia Ġfiles Ġdo Ġnot Ġreturn Ġfile Ġextension . ĠThis Ġfunction Ġhelps Ġyou Ġto Ġfix Ġthis Ġkind Ġof Ġissue . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval ĠfullName : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġif Ġ( is Raw File ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Raw File ()?. name . or Empty () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠmimeType Ġ= Ġget Column Info String ( Media Store . Media Columns . MIME _ TYPE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠdisplayName Ġ= Ġget Column Info String ( Media Store . Media Columns . DISPLAY _ NAME ). or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMime Type . getFull FileName ( displayName , ĠmimeType ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ fullName ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġname : ĠString ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġto Raw File ()?. name Ġ?: Ġget Column Info String ( Media Store . Media Columns . DISPLAY _ NAME ) ĊĊĠĠĠ Ġval Ġbase Name : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠMime Type . getBase FileName ( fullName ) ĊĊĠĠĠ Ġval Ġextension : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠMime Type . getExtension From FileName ( fullName ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see Ġ[ mime Type ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġtype : ĠString ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġto Raw File ()?. name ?. let Ġ{ ĠMime Type . get MimeType From Extension ( MimeType . getExtension From FileName ( it )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġget Column Info String ( Media Store . Media Columns . MIME _ TYPE ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdvanced Ġversion Ġof Ġ[ type ]. ĠReturns Ġ[ MimeType . UNKNOWN ] Ġif Ġthe Ġmime Ġtype Ġis Ġnot Ġfound . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval ĠmimeType : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġget Column Info String ( Media Store . Media Columns . MIME _ TYPE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠMime Type . get MimeType From Extension ( extension ) ĊĊĠĠĠ Ġvar Ġlength : ĠLong ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġto Raw File ()?. length () Ġ?: Ġget Column Info Long ( Media Store . Media Columns . SIZE ) ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Values Ġ= ĠContent Values ( 1 ). apply Ġ{ Ġput ( Media Store . Media Columns . SIZE , Ġvalue ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . update ( uri , Ġcontent Values , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Security Exception ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġformatted Size : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠFormatter . format FileSize ( context , Ġlength ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe ĠURI Ġpresents Ġin ĠS AF Ġdatabase , Ġbut Ġthe Ġfile Ġis Ġnot Ġfound Ġor Ġhas Ġzero Ġlength . ĊĠĠĠĠ Ġ* Ġ@ see Ġhas Zero Length ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval ĠisEmpty : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġpresents In S af Database Ġ&& Ġhas Zero Length ĊĊĠĠĠ Ġval Ġpresents In S af Database : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġcontext . content Resolver . query ( uri , Ġnull , Ġnull , Ġnull , Ġnull )?. use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . count Ġ> Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see ĠisEmpty ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġhas Zero Length : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġuri . open InputStream ( context )?. use Ġ{ Ġstream Ġ-> Ġstream . available () Ġ== Ġ 0 Ġ} Ġ!= Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ` true ` Ġif Ġthis Ġfile Ġwas Ġcreated Ġwith Ġ[ File ]. ĠOnly Ġworks Ġon ĠAPI Ġ 2 8 Ġand Ġlower . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġis Raw File : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġuri . is Raw File ĊĊĠĠĠ Ġval Ġlast Modified : ĠLong ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġto Raw File ()?. lastModified () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġget Column Info Long ( Media Store . Media Columns . DATE _ MODI FIED ) ĊĊĠĠĠ Ġval Ġowner : ĠString ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . Q ) Ġget Column Info String ( Media Store . Media Columns . OWNER _ PACKAGE _ NAME ) Ġelse Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġthis Ġmedia Ġis Ġowned Ġby Ġyour Ġapp . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġis Mine : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġowner Ġ== Ġcontext . packageName ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ return Ġ` null ` Ġin ĠAndroid Ġ 1 0 + Ġor Ġif Ġyou Ġtry Ġto Ġread Ġfiles Ġfrom ĠSD ĠCard Ġor Ġyou Ġwant Ġto Ġconvert Ġa Ġfile Ġpicked ĊĠĠĠĠ Ġ* Ġfrom Ġ[ Intent . ACTION _ OPEN _ DOCUMENT ] Ġor Ġ[ Intent . ACTION _ CREATE _ DOCUMENT ]. ĊĠĠĠĠ Ġ* Ġ@ see Ġto Document File ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Deprecated (" Access ing Ġfiles Ġwith Ġjava . io . File Ġonly Ġworks Ġon Ġapp Ġprivate Ġdirectory Ġsince ĠAndroid Ġ 1 0 .") ĊĠĠĠ Ġfun Ġto Raw File () Ġ= Ġif Ġ( is Raw File ) Ġuri . path ?. let Ġ{ ĠFile ( it ) Ġ} Ġelse Ġnull ĊĊĠĠĠ Ġfun Ġto Document File () Ġ= Ġabsolute Path . let Ġ{ Ġif Ġ( it . isEmpty ()) Ġnull Ġelse ĠDocument File Compat . from FullPath ( context , Ġit ) Ġ} ĊĊĠĠĠ Ġval Ġabsolute Path : ĠString ĊĠĠĠĠĠĠĠ Ġ@ Suppress Lint (" In lined Api ") ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġto Raw File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Ġ!= Ġnull Ġ-> Ġfile . path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBuild . VERSION . SDK _ INT Ġ< ĠBuild . VERSION _ CODES . Q Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . query ( uri , ĠarrayOf ( Media Store . Media Columns . DATA ), Ġnull , Ġnull , Ġnull )?. use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor . getString ( cursor . getColumnIndex ( Media Store . Media Columns . DATA )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprojection Ġ= ĠarrayOf ( Media Store . Media Columns . REL ATIVE _ PATH , ĠMedia Store . Media Columns . DISPLAY _ NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . query ( uri , Ġprojection , Ġnull , Ġnull , Ġnull )?. use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrelative Path Ġ= Ġcursor . getString ( cursor . getColumnIndex ( Media Store . Media Columns . REL ATIVE _ PATH )) Ġ?: Ġreturn Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġcursor . getString ( cursor . getColumnIndex ( Media Store . Media Columns . DISPLAY _ NAME )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ Simple Storage . external Storage Path }/ $ relative Path /$ name ". trim End ('/ '). replace Comp let ely ("// ", Ġ"/") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval ĠbasePath : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġabsolute Path . substring After ( Simple Storage . external Storage Path ). trim File Separator () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see ĠMedia Store . Media Columns . REL ATIVE _ PATH ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġrelative Path : ĠString ĊĠĠĠĠĠĠĠ Ġ@ Suppress Lint (" In lined Api ") ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġto Raw File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Ġ!= Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . path . substring Before Last ('/ '). replace First ( Simple Storage . external Storage Path , Ġ""). trim File Separator () Ġ+ Ġ"/" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBuild . VERSION . SDK _ INT Ġ< ĠBuild . VERSION _ CODES . Q Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . query ( uri , ĠarrayOf ( Media Store . Media Columns . DATA ), Ġnull , Ġnull , Ġnull )?. use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreal Folder AbsolutePath Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor . getString ( cursor . getColumnIndex ( Media Store . Media Columns . DATA )). substring Before Last ('/') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreal Folder AbsolutePath . replace First ( Simple Storage . external Storage Path , Ġ""). trim File Separator () Ġ+ Ġ"/" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprojection Ġ= ĠarrayOf ( Media Store . Media Columns . REL ATIVE _ PATH ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . query ( uri , Ġprojection , Ġnull , Ġnull , Ġnull )?. use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor . getString ( cursor . getColumnIndex ( Media Store . Media Columns . REL ATIVE _ PATH )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdelete (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġto Raw File () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( file Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile . delete () Ġ|| Ġ! file . exists () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . delete ( uri , Ġnull , Ġnull ) Ġ> Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Security Exception ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPlease Ġnote Ġthat Ġthis Ġfunction Ġdoes Ġnot Ġmove Ġfile Ġif Ġyou Ġinput Ġ` new Name ` Ġas Ġ` Download / filename . mp 4 `. ĊĠĠĠĠ Ġ* ĠIf Ġyou Ġwant Ġto Ġmove Ġmedia Ġfiles , Ġplease Ġuse Ġ[ move File To ] Ġinstead . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġrename To ( new Name : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġto Raw File () ĊĠĠĠĠĠĠĠ Ġval Ġcontent Values Ġ= ĠContent Values ( 1 ). apply Ġ{ Ġput ( Media Store . Media Columns . DISPLAY _ NAME , ĠnewName ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( file Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . update ( uri , Ġcontent Values , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile . rename To ( File ( file . parent , ĠnewName )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠUnsupportedOperationException (" Cannot Ġrename Ġmedia Ġfiles Ġon ĠAndroid Ġ 1 0 +") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSet Ġto Ġ` true ` Ġif Ġthe Ġfile Ġis Ġbeing Ġwritten Ġto Ġprevent Ġusers Ġfrom Ġaccessing Ġit . ĊĠĠĠĠ Ġ* Ġ@ see ĠMedia Store . Media Columns . IS _ PENDING ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġis Pending : ĠBoolean ĊĠĠĠĠĠĠĠ Ġ@ Requires Api ( Build . VERSION _ CODES . Q ) ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġget Column Info Int ( Media Store . Media Columns . IS _ PENDING ) Ġ== Ġ 1 ĊĠĠĠĠĠĠĠ Ġ@ Requires Api ( Build . VERSION _ CODES . Q ) ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Values Ġ= ĠContent Values ( 1 ). apply Ġ{ Ġput ( Media Store . Media Columns . IS _ PENDING , Ġvalue . toInt ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . update ( uri , Ġcontent Values , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Security Exception ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Security Exception ( e : ĠSecurity Exception , Ġcallback : ĠFile Callback ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . Q Ġ&& Ġe Ġis ĠRe cover able Security Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaccess Callback ?. on Write Access Denied ( this , Ġe . user Action . action Intent . intent Sender ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback ?. ui Scope ?. post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . STORAGE _ PERMISSION _ DEN IED ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Ui Thread ĊĠĠĠ Ġfun Ġopen File Intent ( authority : ĠString ) Ġ= ĠIntent ( Intent . ACTION _ VIEW ) ĊĠĠĠĠĠĠĠ Ġ. setData ( if Ġ( is Raw File ) ĠFile Provider . get Uri For File ( context , Ġauthority , ĠFile ( uri . path !! )) Ġelse Ġuri ) ĊĠĠĠĠĠĠĠ Ġ. add Flags ( Intent . FLAG _ GRANT _ READ _ URI _ PERMISSION ) ĊĠĠĠĠĠĠĠ Ġ. add Flags ( Intent . FLAG _ ACTIVITY _ NEW _ TASK ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġappend Ġif Ġ` false ` Ġand Ġthe Ġfile Ġalready Ġexists , Ġit Ġwill Ġrecreate Ġthe Ġfile . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġfun Ġopen OutputStream ( append : ĠBoolean Ġ= Ġtrue ): ĠOutputStream ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġto Raw File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFileOutputStream ( file , Ġappend ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . open OutputStream ( uri , Ġif Ġ( append ) Ġ" wa " Ġelse Ġ" w ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġopen InputStream (): ĠInputStream ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġto Raw File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFileInputStream ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . open InputStream ( uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Target Api ( Build . VERSION _ CODES . Q ) ĊĠĠĠ Ġfun Ġmove To ( relative Path : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontent Values Ġ= ĠContent Values ( 1 ). apply Ġ{ Ġput ( Media Store . Media Columns . REL ATIVE _ PATH , Ġrelative Path ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . content Resolver . update ( uri , Ġcontent Values , Ġnull , Ġnull ) Ġ> Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Security Exception ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġmove To ( target Folder : ĠDocument File , Ġfile Description : ĠFile Description ? Ġ= Ġnull , Ġcallback : ĠFile Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsource File Ġ= Ġto Document File () ĊĠĠĠĠĠĠĠ Ġif Ġ( source File Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource File . move File To ( context , Ġtarget Folder , Ġfile Description , Ġcallback ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! callback . on Check Free Space ( Document File Compat . get Free Space ( context , Ġtarget Folder . get Storage Id ( context )), Ġlength )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . NO _ SPACE _ LEFT _ ON _ TARGET _ PATH ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtarget Directory Ġ= Ġif Ġ( file Description ?. sub Folder . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Folder ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdirectory Ġ= Ġtarget Folder . make Folder ( context , Ġfile Description ?. sub Folder . or Empty (), ĠCreate Mode . RE USE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( directory Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . CAN NOT _ CREATE _ FILE _ IN _ TARGET ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirectory ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġclean FileName Ġ= ĠMime Type . getFull FileName ( file Description ?. name Ġ?: Ġname . or Empty (), Ġfile Description ?. mime Type Ġ?: Ġtype ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. remove Forbidden Chars From Filename (). trim File Separator () ĊĠĠĠĠĠĠĠ Ġval Ġconflict Resolution Ġ= Ġhandle File Conflict ( target Directory , Ġclean FileName , Ġcallback ) ĊĠĠĠĠĠĠĠ Ġif Ġ( conflict Resolution Ġ== ĠFile Callback . Conflict Resolution . SKIP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġthread Ġ= ĠThread . currentThread () ĊĠĠĠĠĠĠĠ Ġval Ġreport Interval Ġ= Ġawait Ui Result ( callback . ui Scope ) Ġ{ Ġcallback . onStart ( this , Ġthread ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġwatch Progress Ġ= Ġreport Interval Ġ> Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget File Ġ= Ġcreate Target File ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Directory , Ġclean FileName , Ġfile Description ?. mime Type Ġ?: Ġtype , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconflict Resolution . to Create Mode (), Ġcallback ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate File Streams ( target File , Ġcallback ) Ġ{ ĠinputStream , ĠoutputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcopy FileStream ( inputStream , ĠoutputStream , Ġtarget File , Ġwatch Progress , Ġreport Interval , Ġtrue , Ġcallback ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Security Exception ( e , Ġcallback ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( e . to File Callback ErrorCode ()) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġcopy To ( target Folder : ĠDocument File , Ġfile Description : ĠFile Description ? Ġ= Ġnull , Ġcallback : ĠFile Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsource File Ġ= Ġto Document File () ĊĠĠĠĠĠĠĠ Ġif Ġ( source File Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource File . copy File To ( context , Ġtarget Folder , Ġfile Description , Ġcallback ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! callback . on Check Free Space ( Document File Compat . get Free Space ( context , Ġtarget Folder . get Storage Id ( context )), Ġlength )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . NO _ SPACE _ LEFT _ ON _ TARGET _ PATH ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtarget Directory Ġ= Ġif Ġ( file Description ?. sub Folder . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Folder ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdirectory Ġ= Ġtarget Folder . make Folder ( context , Ġfile Description ?. sub Folder . or Empty (), ĠCreate Mode . RE USE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( directory Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . CAN NOT _ CREATE _ FILE _ IN _ TARGET ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirectory ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġclean FileName Ġ= ĠMime Type . getFull FileName ( file Description ?. name Ġ?: Ġname . or Empty (), Ġfile Description ?. mime Type Ġ?: Ġtype ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. remove Forbidden Chars From Filename (). trim File Separator () ĊĠĠĠĠĠĠĠ Ġval Ġconflict Resolution Ġ= Ġhandle File Conflict ( target Directory , Ġclean FileName , Ġcallback ) ĊĠĠĠĠĠĠĠ Ġif Ġ( conflict Resolution Ġ== ĠFile Callback . Conflict Resolution . SKIP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġthread Ġ= ĠThread . currentThread () ĊĠĠĠĠĠĠĠ Ġval Ġreport Interval Ġ= Ġawait Ui Result ( callback . ui Scope ) Ġ{ Ġcallback . onStart ( this , Ġthread ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġwatch Progress Ġ= Ġreport Interval Ġ> Ġ 0 ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget File Ġ= Ġcreate Target File ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Directory , Ġclean FileName , Ġfile Description ?. mime Type Ġ?: Ġtype , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconflict Resolution . to Create Mode (), Ġcallback ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate File Streams ( target File , Ġcallback ) Ġ{ ĠinputStream , ĠoutputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcopy FileStream ( inputStream , ĠoutputStream , Ġtarget File , Ġwatch Progress , Ġreport Interval , Ġfalse , Ġcallback ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Security Exception ( e , Ġcallback ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( e . to File Callback ErrorCode ()) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Target File ( ĊĠĠĠĠĠĠĠ Ġtarget Directory : ĠDocument File , ĊĠĠĠĠĠĠĠ ĠfileName : ĠString , ĊĠĠĠĠĠĠĠ ĠmimeType : ĠString ?, ĊĠĠĠĠĠĠĠ Ġmode : ĠCreate Mode , ĊĠĠĠĠĠĠĠ Ġcallback : ĠFile Callback ĊĠĠĠ Ġ): ĠDocument File ? Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġabsolute Path Ġ= ĠDocument File Compat . build AbsolutePath ( context , Ġtarget Directory . get Storage Id ( context ), Ġtarget Directory . getBase Path ( context )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Folder Ġ= ĠDocument File Compat . mkdir s ( context , Ġabsolute Path ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( target Folder Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . STORAGE _ PERMISSION _ DEN IED ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget File Ġ= Ġtarget Folder . make File ( context , ĠfileName , ĠmimeType , Ġmode ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( target File Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . CAN NOT _ CREATE _ FILE _ IN _ TARGET ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtarget File ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Security Exception ( e , Ġcallback ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( e . to File Callback ErrorCode ()) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinline Ġfun Ġcreate File Streams ( ĊĠĠĠĠĠĠĠ Ġtarget File : ĠDocument File , ĊĠĠĠĠĠĠĠ Ġcallback : ĠFile Callback , ĊĠĠĠĠĠĠĠ Ġon Streams Ready : Ġ( InputStream , ĠOutputStream ) Ġ-> ĠUnit ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠoutputStream Ġ= Ġtarget File . open OutputStream ( context ) ĊĠĠĠĠĠĠĠ Ġif Ġ( output Stream Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . TARGET _ FILE _ NOT _ FOUND ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġopen InputStream () ĊĠĠĠĠĠĠĠ Ġif Ġ( inputStream Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . SOURCE _ FILE _ NOT _ FOUND ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . close Stream Quiet ly () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġon Streams Ready ( inputStream , ĠoutputStream ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcopy FileStream ( ĊĠĠĠĠĠĠĠ ĠinputStream : ĠInputStream , ĊĠĠĠĠĠĠĠ ĠoutputStream : ĠOutputStream , ĊĠĠĠĠĠĠĠ Ġtarget File : ĠDocument File , ĊĠĠĠĠĠĠĠ Ġwatch Progress : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġreport Interval : ĠLong , ĊĠĠĠĠĠĠĠ Ġdelete SourceFile When Complete : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġcallback : ĠFile Callback ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġtimer : ĠJob ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbytes Moved Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġwrite Speed Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsrc Size Ġ= Ġlength ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġusing Ġtimer Ġon Ġsmall Ġfile Ġis Ġuseless . ĠWe Ġset Ġminimum Ġ 1 0 MB . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( watch Progress Ġ&& Ġsrc Size Ġ> Ġ 1 0 Ġ* ĠFile Size . MB ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimer Ġ= Ġstart Coroutine Timer ( repeat Millis Ġ= Ġreport Interval ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreport Ġ= ĠFile Callback . Report ( bytes Moved Ġ* Ġ 1 0 0 f Ġ/ Ġsrc Size , Ġbytes Moved , Ġwrite Speed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Report ( report ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite Speed Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( DEFAULT _ BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġread Ġ= ĠinputStream . read ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( read Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . write ( buffer , Ġ 0 , Ġread ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbytes Moved Ġ+= Ġread ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite Speed Ġ+= Ġread ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread Ġ= ĠinputStream . read ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtimer ?. cancel () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( delete SourceFile When Complete ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Completed ( target File ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtimer ?. cancel () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream . close Stream Quiet ly () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . close Stream Quiet ly () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle File Conflict ( ĊĠĠĠĠĠĠĠ Ġtarget Folder : ĠDocument File , ĊĠĠĠĠĠĠĠ ĠfileName : ĠString , ĊĠĠĠĠĠĠĠ Ġcallback : ĠFile Callback ĊĠĠĠ Ġ): ĠFile Callback . Conflict Resolution Ġ{ ĊĠĠĠĠĠĠĠ Ġtarget Folder . child ( context , ĠfileName )?. let Ġ{ Ġtarget File Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresolution Ġ= Ġawait Ui Result With Pending < File Callback . Conflict Resolution >( callback . ui Scope ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . on Conflict ( target File , ĠFile Callback . File Conflict Action ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( resolution Ġ== ĠFile Callback . Conflict Resolution . REPLACE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! target File . force Delete ( context )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . ui Scope . post To Ui Ġ{ Ġcallback . on Failed ( File Callback . ErrorCode . CAN NOT _ CREATE _ FILE _ IN _ TARGET ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFile Callback . Conflict Resolution . SKIP ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresolution ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠFile Callback . Conflict Resolution . CREATE _ NEW ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Column Info String ( column : ĠString ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . query ( uri , ĠarrayOf ( column ), Ġnull , Ġnull , Ġnull )?. use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠcolumnIndex Ġ= Ġcursor . getColumnIndex ( column ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( column Index Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcursor . getString ( column Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Column Info Long ( column : ĠString ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . query ( uri , ĠarrayOf ( column ), Ġnull , Ġnull , Ġnull )?. use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠcolumnIndex Ġ= Ġcursor . getColumnIndex ( column ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( column Index Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcursor . getLong ( column Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Column Info Int ( column : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . query ( uri , ĠarrayOf ( column ), Ġnull , Ġnull , Ġnull )?. use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠcolumnIndex Ġ= Ġcursor . getColumnIndex ( column ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( column Index Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcursor . getInt ( column Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?) Ġ= Ġother Ġ=== Ġthis Ġ|| Ġother Ġis ĠMedia File Ġ&& Ġother . uri Ġ== Ġuri ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode () Ġ= Ġuri . hashCode () ĊĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġuri . toString () Ċ }