package Ġeu . sch n uff . bon fo Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . content . Content U ris Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . database . Cursor Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . Environment Ċ import Ġandroid . provider . Documents Contract Ċ import Ġandroid . provider . Media Store Ċ import Ġandroid . view . View Ċ import Ġandroid . widget . Array Adapter Ċ import Ġandroidx . preference . Preference Fragment Compat Ċ import Ġeu . sch n uff . bon fo . dummy . Setting Ċ import Ġeu . sch n uff . bon fo . helpers . permission External Storage Helper Ċ import Ġjava . util .* ĊĊ Ċ private Ġconst Ġval ĠOPEN _ DIRECTORY _ REQUEST _ CODE Ġ= Ġ 1 Ċ Ċ class ĠPreference General Ġ: ĠPreference Fragment Compat () Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġdir Adapter : ĠArray Adapter < String >? Ġ= Ġnull ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate Preferences ( savedInstanceState : ĠBundle ?, Ġroot Key : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġset Preferences From Resource ( R . xml . pref _ general , Ġroot Key ) ĊĊĠĠĠĠĠĠĠ ĠSetting . load ( context !! ) ĊĠĠĠĠĠĠĠ Ġdir Adapter Ġ= ĠArray Adapter ( context !! , ĠR . layout . simple _ text _ view , ĠArrayList ( Setting . w atched Directory )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġoverride Ġfun Ġon View Created ( view : ĠView , ĠsavedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on View Created ( view , ĠsavedInstanceState ) ĊĠĠĠĠĠĠĠ Ġval Ġdir Lister Ġ= Ġpreference Screen . find Preference < Preference Dir Lister >(" selected _ directories ") !! ĊĠĠĠĠĠĠĠ Ġdir Lister . on Add Listener Ġ= Ġ{ Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpermission External Storage Helper ( context !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠIntent ( Intent . ACTION _ OPEN _ DOCUMENT _ TREE ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags Ġ= ĠIntent . FLAG _ GRANT _ READ _ URI _ PERMISSION Ġ// Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Intent . FLAG _ GRANT _ PER SIST ABLE _ URI _ PERMISSION ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartActivity For Result ( intent , ĠOPEN _ DIRECTORY _ REQUEST _ CODE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdir Lister . dir Adapter Ġ= Ġdir Adapter ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠĠĠĠĠ Ġif Ġ( request Code Ġ== ĠOPEN _ DIRECTORY _ REQUEST _ CODE Ġ&& ĠresultCode Ġ== ĠActivity . RESULT _ OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuri Ġ= Ġdata ?. data Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* context !!. content Resolver . take Persist able Uri Permission ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirectory Uri , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent . FLAG _ GRANT _ READ _ URI _ PERMISSION ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) */ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdoc Uri Ġ= ĠDocuments Contract . build Document Uri Using Tree ( uri , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDocuments Contract . get Tree Document Id ( uri )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdirectory Uri Ġ= ĠgetPath ( context !! , Ġdoc Uri ) !! ĊĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠSetting . add Path ( context !! , Ġdirectory Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdir Adapter !!. add ( directory Uri . toString ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetPath ( context : ĠContext , Ġuri : ĠUri ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠDocument Provider ĊĠĠĠĠĠĠĠ Ġif Ġ( Documents Contract . is Document Uri ( context , Ġuri )) Ġ{ Ġ// ĠExternal Storage Provider ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is External Storage Document ( uri )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdoc Id Ġ= ĠDocuments Contract . getDocument Id ( uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsplit Ġ= Ġdoc Id . split (": "). to Typed Array () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġsplit [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(" primary ". equals ( type , Ġignore Case Ġ= Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠEnvironment . get External Storage Directory (). toString () Ġ+ Ġ"/" Ġ+ Ġsplit [ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO Ġhandle Ġnon - primary Ġvolumes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( is Downloads Document ( uri )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= ĠDocuments Contract . getDocument Id ( uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Uri : ĠUri Ġ= ĠContent U ris . with App ended Id ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUri . parse (" content :// downloads / public _ downloads "), Ġjava . lang . Long . valueOf ( id )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠgetData Column ( context , Ġcontent Uri , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( is Media Document ( uri )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdoc Id Ġ= ĠDocuments Contract . getDocument Id ( uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsplit Ġ= Ġdoc Id . split (": "). to Typed Array () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Uri Ġ= Ġwhen Ġ( split [ 0 ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" image " Ġ-> ĠMedia Store . Images . Media . EXTERNAL _ CONTENT _ URI ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" video " Ġ-> ĠMedia Store . Video . Media . EXTERNAL _ CONTENT _ URI ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" audio " Ġ-> ĠMedia Store . Audio . Media . EXTERNAL _ CONTENT _ URI ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠTODO (" content Ġtype Ġ'${ split [ 0 ]} ' Ġis Ġnot Ġsupported .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"_ id = ?" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġselection Args Ġ= ĠarrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsplit [ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠgetData Column ( context , Ġcontent Uri , Ġselection , Ġselection Args ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(" content ". equals ( uri . scheme , Ġignore Case Ġ= Ġtrue )) Ġ{ Ġ// ĠReturn Ġthe Ġremote Ġaddress ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( is Google Photos Uri ( uri )) Ġuri . last Path Segment Ġelse ĠgetData Column ( context , Ġuri , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(" file ". equals ( uri . scheme , Ġignore Case Ġ= Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġuri . path ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠTODO (" could Ġnot Ġresolve Ġuri Ġ'${ uri . toString ()} '. ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetData Column ( context : ĠContext , Ġuri : ĠUri , Ġselection : ĠString ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselection Args : ĠArray < String >? ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcursor : ĠCursor ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġcolumn Ġ= Ġ"_ data " ĊĠĠĠĠĠĠĠ Ġval Ġprojection Ġ= ĠarrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolumn ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcursor Ġ= Ġcontext . content Resolver . query ( uri , Ġprojection , Ġselection , Ġselection Args , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor Ġ!= Ġnull Ġ&& Ġcursor . moveTo First ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġindex : ĠInt Ġ= Ġcursor . getColumnIndex OrThrow ( column ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcursor . getString ( index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcursor ?. close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġuri ĠThe ĠUri Ġto Ġcheck . ĊĠĠĠĠ Ġ* Ġ@ return ĠWhether Ġthe ĠUri Ġauthority Ġis ĠExternal Storage Provider . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġis External Storage Document ( uri : ĠUri ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" com . android . external storage . documents " Ġ== Ġuri . get Authority () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġuri ĠThe ĠUri Ġto Ġcheck . ĊĠĠĠĠ Ġ* Ġ@ return ĠWhether Ġthe ĠUri Ġauthority Ġis ĠDown loads Provider . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġis Downloads Document ( uri : ĠUri ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" com . android . providers . downloads . documents " Ġ== Ġuri . get Authority () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġuri ĠThe ĠUri Ġto Ġcheck . ĊĠĠĠĠ Ġ* Ġ@ return ĠWhether Ġthe ĠUri Ġauthority Ġis ĠMedia Provider . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġis Media Document ( uri : ĠUri ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" com . android . providers . media . documents " Ġ== Ġuri . get Authority () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġuri ĠThe ĠUri Ġto Ġcheck . ĊĠĠĠĠ Ġ* Ġ@ return ĠWhether Ġthe ĠUri Ġauthority Ġis ĠGoogle ĠPh otos . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġis Google Photos Uri ( uri : ĠUri ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" com . google . android . apps . photos . content " Ġ== Ġuri . get Authority () ĊĠĠĠ Ġ} Ċ } Ċ