package Ġme . phantom x . download manager . ab str acs . ui Ċ Ċ import Ġandroid . Manifest Ċ import Ġandroid . content .* Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . IB inder Ċ import Ġandroid . provider . Settings Ċ import Ġandroid . util . Log Ċ import Ġandroid . widget . Toast Ċ import Ġandroidx . activity . result . contract . Activity Result Contracts Ċ import Ġandroidx . appcompat . app . AlertDialog Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġandroidx . lifecycle . lifecycle Scope Ċ import Ġandroidx . local broadcast manager . content . Local Broadcast Manager Ċ import Ġandroidx . recyclerview . widget . Linear LayoutManager Ċ import Ġdagger . h ilt . android . Android EntryPoint Ċ import Ġkotlinx . coroutines . Dispatch ers . Main Ċ import Ġkotlinx . coroutines . delay Ċ import Ġkotlinx . coroutines . launch Ċ import Ġme . phantom x . download manager . ab str acs . services . App Service Ċ import Ġme . phantom x . download manager . adapter . Download Adapter Ċ import Ġme . phantom x . download manager . data . File Download Ċ import Ġme . phantom x . download manager . database . Repository Ċ import Ġme . phantom x . download manager . databinding . Activity Main Binding Ċ import Ġme . phantom x . download manager . extensions . has Permissions Ċ import Ġme . phantom x . download manager . extensions . isRunning Service Ċ import Ġme . phantom x . download manager . services . Download Service Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġjava . io . File Ċ import Ġjavax . inject . Inject Ċ Ċ @ Android EntryPoint Ċ abstract Ġclass ĠMain Screen : ĠAppCompatActivity (), ĠObserver < File Download >, ĠService Connection Ġ{ ĊĊĠĠĠ Ġlateinit Ġvar Ġbinding : ĠActivity Main Binding ĊĠĠĠ Ġlateinit Ġvar Ġdownload Service : ĠDownload Service ĊĠĠĠ Ġlateinit Ġvar Ġadapter : ĠDownload Adapter ĊĊĠĠĠ Ġprivate Ġval Ġpermissions Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠ ĠManifest . permission . READ _ EXTERNAL _ STORAGE , ĊĠĠĠĠĠĠĠ ĠManifest . permission . WRITE _ EXTERNAL _ STORAGE ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġval Ġrequest Code Permission Ġ= Ġ 2 2 ĊĠĠĠ Ġval Ġdownload List : ĠMutable List < File Download > Ġ= ĠArrayList () ĊĊĠĠĠ Ġprivate Ġvar Ġdialog : ĠAlertDialog ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar Ġok client : ĠOk HttpClient ĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar Ġrepository : ĠRepository ĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar Ġdirectory : ĠFile ĊĊĠĠĠ Ġprivate Ġvar Ġbroadcast Receiver Ġ= Ġobject Ġ: ĠBroadcast Receiver () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Receive ( context : ĠContext ?, Ġintent : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġintent ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . get Serializable Extra (" job ") ?. let Ġ{ Ġserialize Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( serialize Ġas ĠFile Download ). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload List . add ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload Service . run Job ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrepository . put ( this @ run ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadapter . notify Item Inserted ( download List . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Directory () Ġ= Ġdirectory . run Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! exists ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( java Class . name , Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmkdir () Ġ-> Ġ" onCreate : ĠDir ĠCreated " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmkdir s () Ġ-> Ġ Ġ" onCreate : ĠDir ĠCreated " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ Ġ" onCreate : ĠFailed Ġcreate Ġdirectory " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġfun ĠonCreate Activity ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! isRunning Service ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmy Service Ġ= ĠIntent ( this , ĠDownload Service :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . O ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Foreground Service ( my Service ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Service ( my Service ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbind Service ( my Service , Ġthis , ĠContext . BIND _ AUTO _ CREATE ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠLocal Broadcast Manager . getInstance ( this ). register Receiver ( broadcast Receiver , ĠIntent Filter (" DM - Request ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ Ġbinding Ġ= ĠActivity Main Binding . inflate ( layout Inflater ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( binding . root ) ĊĠĠĠĠĠĠĠ ĠonCreate Activity ( savedInstanceState ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Destroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġun bind Service ( this ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsuper . on Destroy () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Permissions (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! has Permissions ( permissions ) Ġ&& ĠBuild . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . M ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Permissions () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Directory () ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrequest Permissions () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( dialog Ġ!= Ġnull ) Ġreturn ĊĠĠĠĠĠĠĠ ĠAlertDialog . Builder ( this ). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsetTitle (" Need Ġstorage Ġper mis ion ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Message (" Please Ġallow Ġstorage Ġpermission Ġfirst !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Positive Button ( android . R . string . ok ) Ġ{ Ġdialog , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . R ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( Settings . ACTION _ MANAGE _ ALL _ FILES _ ACCESS _ PERMISSION ). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġ= ĠUri . parse (" package :${ packageName }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactivity Result Launcher . launch ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactivity Result Launcher . launch ( Intent ( Settings . ACTION _ MANAGE _ ALL _ FILES _ ACCESS _ PERMISSION )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ set Positive Button ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . M ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Permissions ( permissions . to Typed Array (), Ġrequest Code Permission ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Negative Button ( android . R . string . cancel ) Ġ{ Ġdialog , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdialog . dismiss () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! has Permissions ( permissions ) Ġ&& ĠBuild . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . M ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset On Dismiss Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdialog Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Cancel able ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdialog Ġ= Ġshow () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġactivity Result Launcher Ġ= Ġregister For Activity Result ( Activity Result Contracts . Start Activity For Result () ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( it . result Code Ġ== ĠRESULT _ OK Ġ&& Ġ! has Permissions ( permissions )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this , Ġ" App Ġdoesn 't Ġwork Ġwithout Ġstorage Ġpermission !", ĠToast . LENGTH _ SHORT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. show () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 5 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Directory () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Request Permissions Result ( ĊĠĠĠĠĠĠĠ Ġrequest Code : ĠInt , ĊĠĠĠĠĠĠĠ Ġpermission : ĠArray < out ĠString >, ĊĠĠĠĠĠĠĠ Ġgrant Results : ĠInt Array ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Request Permissions Result ( request Code , Ġpermission , Ġgrant Results ) ĊĠĠĠĠĠĠĠ Ġif Ġ( request Code Ġ!= Ġrequest Code Permission ) Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ(! has Permissions ( permissions )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this , Ġ" App Ġdoesn 't Ġwork Ġwithout Ġstorage Ġpermission !", ĠToast . LENGTH _ SHORT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. show () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 5 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Directory () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonChanged ( t : ĠFile Download ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadapter . notify Item Changed ( download List . indexOf ( t ), ĠUnit ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Service Connected ( name : ĠComponent Name ?, Ġservice : ĠI Binder ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġdownload Service Ġ= Ġ( service Ġas ĠApp Service . Local Binder ). getService () Ġas ĠDownload Service ĊĠĠĠĠĠĠĠ Ġdownload Service . live Data . observe ( this , Ġthis ) ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch ( Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadapter Ġ= ĠDownload Adapter ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload List , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . coroutine Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload Service , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrepository ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . recycler . layout Manager Ġ= ĠLinearLayoutManager ( this @ Main Screen ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . recycler . adapter Ġ= Ġadapter ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Service Disconnected ( name : ĠComponent Name ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġdownload Service . live Data . remove Observer ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Resume () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Resume () ĊĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . R ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Permissions () ĊĠĠĠ Ġ} Ċ Ċ }