package Ġvn . hun gh d . flutter downloader Ċ Ċ import Ġandroid . Manifest Ċ import Ġandroid . app . Notification Channel Ċ import Ġandroid . app . Notification Manager Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . content . Content Resolver Ċ import Ġandroid . content . Content Values Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . pm . Application Info Ċ import Ġandroid . content . pm . PackageManager Ċ import Ġandroid . content . res . Asset Manager Ċ import Ġandroid . content . res . Resources Ċ import Ġandroid . media . Media Scanner Connection Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Environment Ċ import Ġandroid . os . Handler Ċ import Ġandroid . provider . Media Store Ċ import Ġandroid . text . TextUtils Ċ import Ġandroid . util . Log Ċ import Ġandroidx . annotation . Requires Api Ċ import Ġandroidx . core . app . Notification Compat Ċ import Ġandroidx . core . app . Notification Manager Compat Ċ import Ġandroidx . core . content . Context Compat Ċ import Ġandroidx . work . Worker Ċ import Ġandroidx . work . Worker Parameters Ċ import Ġio . flutter . Flutter Injector Ċ import Ġio . flutter . embedding . engine . Flutter Engine Ċ import Ġio . flutter . embedding . engine . dart . Dart Executor Ċ import Ġio . flutter . plugin . common . MethodCall Ċ import Ġio . flutter . plugin . common . Method Channel Ċ import Ġio . flutter . view . Flutter Callback Information Ċ import Ġorg . json . JSONException Ċ import Ġorg . json . JSONObject Ċ import Ġjava . io .* Ċ import Ġjava . net . Http URLConnection Ċ import Ġjava . net . URL Ċ import Ġjava . net . URL Decoder Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ import Ġjava . util . regex . Pattern Ċ import Ġkotlin . collections . Array Deque Ċ import Ġkotlin . collections . ArrayList Ċ import Ġkotlin . collections . HashMap Ċ Ċ class ĠDownload Worker ( ĊĠĠĠ Ġcontext : ĠContext , ĊĠĠĠ Ġparams : ĠWorker Parameters Ċ ) Ġ: ĠWorker ( context , Ġparams ), ĊĠĠĠ ĠMethod Channel . MethodCall Handler Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcharset Pattern Ġ= ĠPattern . compile (" (? i )\\ b charset = \\ s * \" ? ([^ \\ s ;\ "] *) ") ĊĠĠĠ Ġprivate Ġval Ġfilename Star Pattern Ġ= ĊĠĠĠĠĠĠĠ ĠPattern . compile (" (? i )\\ bf ilename \\ *= ([^ '] + )' ([^ '] *) ' \" ? ([ ^\ "] +) \" ?") ĊĠĠĠ Ġprivate Ġval Ġfilename Pattern Ġ= ĠPattern . compile (" (? i )\\ bf ilename =\" ? ([ ^\ "] +) \" ?") ĊĠĠĠ Ġprivate Ġvar Ġbackground Channel : ĠMethod Channel ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġdb Helper : ĠTask Db Helper ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġtask Dao : ĠTask Dao ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġshow Notification Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġclick To Open Downloaded File Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġdebug Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġlast Progress Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġprimary Id Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġmsg Started : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġmsg InProgress : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġmsg Canceled : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġmsg Failed : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġmsg Paused : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġmsg Complete : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġlast Call Update Notification : ĠLong Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġsave In Public Storage Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġfun Ġstart Background Is olate ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsynchronized ( isolate Started ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( background Flutter Engine Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpref Ġ= Ġcontext . get SharedPreferences ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFlutter Downloader Plugin . SHARED _ PREFER ENCES _ KEY , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext . MODE _ PRIVATE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcallback Handle Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpref . getLong ( Flutter Downloader Plugin . CALLBACK _ DISPATCH ER _ HANDLE _ KEY , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Flutter Engine Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFlutter Engine ( application Context ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġneed Ġto Ġcreate Ġan Ġinstance Ġof Ġ` Flutter Engine ` Ġbefore Ġlooking Ġup Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcallback . ĠIf Ġwe Ġdon 't , Ġthe Ġcallback Ġcache Ġwon 't Ġbe Ġinitialized Ġand Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġlookup Ġwill Ġfail . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflutter Callback : ĠFlutter Callback Information Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFlutter Callback Information . lookup Callback Information ( callback Handle ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġapp Bundle Path : ĠString Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFlutter Injector . instance (). flutter Loader (). find App Bundle Path () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġassets : ĠAsset Manager Ġ= Ġapplication Context . assets ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Flutter Engine !!. dart Executor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. execute Dart Callback ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDart Executor . Dart Callback ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassets , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Bundle Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflutter Callback ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbackground Channel Ġ= ĠMethod Channel ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Flutter Engine !!. dart Executor , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" vn . hun gh d / downloader _ background " ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġbackground Channel !!. set MethodCall Handler ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon MethodCall ( call : ĠMethod Call , Ġresult : ĠMethod Channel . Result ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( call . method . equals (" did Initialize Dispatcher ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( isolate Started ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ(! isolate Queue . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Channel ?. invoke Method ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġisolate Queue . remove First () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġisolate Started . set ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . success ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . not Implemented () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Stopped () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext : ĠContext Ġ= Ġapplication Context ĊĠĠĠĠĠĠĠ Ġdb Helper Ġ= ĠTask Db Helper . getInstance ( context ) ĊĠĠĠĠĠĠĠ Ġtask Dao Ġ= Ġdb Helper ?. let Ġ{ ĠTask Dao ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġfilename : ĠString ? Ġ= Ġinput Data . getString ( ARG _ FILE _ NAME ) ĊĠĠĠĠĠĠĠ Ġval Ġtask : ĠDownload Task ? Ġ= Ġtask Dao ?. load Task ( id . toString ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( task ?. status Ġ== ĠDownload Status . EN QUE U ED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Notification ( context , Ġfilename , ĠDownload Status . C ANCE LED , Ġ- 1 , Ġnull , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), ĠDownload Status . C ANCE LED , Ġlast Progress ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdo Work (): ĠResult Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext : ĠContext Ġ= Ġapplication Context ĊĠĠĠĠĠĠĠ Ġdb Helper Ġ= ĠTask Db Helper . getInstance ( context ) ĊĠĠĠĠĠĠĠ Ġtask Dao Ġ= Ġdb Helper ?. let Ġ{ ĠTask Dao ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġurl : ĠString ? Ġ= Ġinput Data . getString ( ARG _ URL ) ĊĠĠĠĠĠĠĠ Ġval Ġfilename : ĠString ? Ġ= Ġinput Data . getString ( ARG _ FILE _ NAME ) ĊĠĠĠĠĠĠĠ Ġval Ġsaved Dir : ĠString ? Ġ= Ġinput Data . getString ( ARG _ SA VED _ DIR ) ĊĠĠĠĠĠĠĠ Ġval Ġheaders : ĠString ? Ġ= Ġinput Data . getString ( ARG _ HEADERS ) ĊĠĠĠĠĠĠĠ Ġvar Ġis Resume : ĠBoolean Ġ= Ġinput Data . getBoolean ( ARG _ IS _ RE SU ME , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġdebug Ġ= Ġinput Data . getBoolean ( ARG _ DEBUG , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġval Ġres : ĠResources Ġ= Ġapplication Context . resources ĊĠĠĠĠĠĠĠ Ġmsg Started Ġ= Ġres . getString ( R . string . flutter _ downloader _ notification _ started ) ĊĠĠĠĠĠĠĠ Ġmsg InProgress Ġ= Ġres . getString ( R . string . flutter _ downloader _ notification _ in _ progress ) ĊĠĠĠĠĠĠĠ Ġmsg Canceled Ġ= Ġres . getString ( R . string . flutter _ downloader _ notification _ c anceled ) ĊĠĠĠĠĠĠĠ Ġmsg Failed Ġ= Ġres . getString ( R . string . flutter _ downloader _ notification _ failed ) ĊĠĠĠĠĠĠĠ Ġmsg Paused Ġ= Ġres . getString ( R . string . flutter _ downloader _ notification _ paused ) ĊĠĠĠĠĠĠĠ Ġmsg Complete Ġ= Ġres . getString ( R . string . flutter _ downloader _ notification _ complete ) ĊĠĠĠĠĠĠĠ Ġval Ġtask : ĠDownload Task ? Ġ= Ġtask Dao ?. load Task ( id . toString ()) ĊĠĠĠĠĠĠĠ Ġlog (" Download Worker { url =" Ġ+ Ġurl Ġ+ Ġ", filename =" Ġ+ Ġfilename Ġ+ Ġ", saved Dir =" Ġ+ Ġsaved Dir Ġ+ Ġ", header =" Ġ+ Ġheaders Ġ+ Ġ", is Resume =" Ġ+ Ġis Resume Ġ+ Ġ", status =" Ġ+ Ġif Ġ( task Ġ!= Ġnull ) Ġtask . status Ġelse Ġ" GONE ") ĊĊĠĠĠĠĠĠĠ Ġ// ĠTask Ġhas Ġbeen Ġdeleted Ġor Ġcancelled ĊĠĠĠĠĠĠĠ Ġif Ġ( task Ġ== Ġnull Ġ|| Ġtask . status Ġ== ĠDownload Status . C ANCE LED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . success () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġshow Notification Ġ= Ġinput Data . getBoolean ( ARG _ SHOW _ NOTIFICATION , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġclick To Open Downloaded File Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput Data . getBoolean ( ARG _ OPEN _ FILE _ FROM _ NOTIFICATION , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġsave In Public Storage Ġ= Ġinput Data . getBoolean ( ARG _ SAVE _ IN _ PUBLIC _ STORAGE , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġprimary Id Ġ= Ġtask . primary Id ĊĠĠĠĠĠĠĠ Ġsetup Notification ( context ) ĊĠĠĠĠĠĠĠ Ġupdate Notification ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfilename , ĠDownload Status . RUNNING , Ġtask . progress , Ġnull , Ġfalse ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), ĠDownload Status . RUNNING , Ġtask . progress ) ĊĊĠĠĠĠĠĠĠ Ġ// automatic Ġresume Ġfor Ġpartial Ġfiles . Ġ( if Ġthe Ġwork manager Ġunexpected ly Ġqu ited Ġin Ġbackground ) ĊĠĠĠĠĠĠĠ Ġval Ġsave FilePath Ġ= Ġsaved Dir Ġ+ ĠFile . separator Ġ+ Ġfilename ĊĠĠĠĠĠĠĠ Ġval Ġpartial File Ġ= ĠFile ( save FilePath ) ĊĠĠĠĠĠĠĠ Ġif Ġ( partial File . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Resume Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" exists Ġfile Ġfor Ġ" Ġ+ Ġfilename Ġ+ Ġ" automatic Ġres uming ...") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( url Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( saved Dir Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( headers Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload File ( context , Ġurl , Ġsaved Dir , Ġfilename , Ġheaders , Ġis Resume ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclean Up () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb Helper Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResult . success () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Notification ( context , Ġfilename , ĠDownload Status . FAILED , Ġ- 1 , Ġnull , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), ĠDownload Status . FAILED , Ġlast Progress ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb Helper Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResult . failure () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Headers ( conn : ĠHttp URLConnection ?, Ġheaders : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! TextUtils . isEmpty ( headers )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Headers Ġ= Ġ$ headers ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjson Ġ= ĠJSONObject ( headers ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġit Ġ= Ġjson . keys () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( it . hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġit . next () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconn !!. setRequest Property ( key , Ġjson . getString ( key )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconn !!. do Input Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Partial Downloaded Data Header ( ĊĠĠĠĠĠĠĠ Ġconn : ĠHttp URLConnection ?, ĊĠĠĠĠĠĠĠ Ġfilename : ĠString ?, ĊĠĠĠĠĠĠĠ Ġsaved Dir : ĠString ĊĠĠĠ Ġ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsave FilePath Ġ= Ġsaved Dir Ġ+ ĠFile . separator Ġ+ Ġfilename ĊĠĠĠĠĠĠĠ Ġval Ġpartial File Ġ= ĠFile ( save FilePath ) ĊĠĠĠĠĠĠĠ Ġval Ġdownloaded Bytes Ġ= Ġpartial File . length () ĊĠĠĠĠĠĠĠ Ġlog (" Resume Ġdownload : ĠRange : Ġbytes =$ downloaded Bytes - ") ĊĠĠĠĠĠĠĠ Ġconn !!. setRequest Property (" Accept - Encoding ", Ġ" identity ") ĊĠĠĠĠĠĠĠ Ġconn . setRequest Property (" Range ", Ġ" bytes =$ downloaded Bytes - ") ĊĠĠĠĠĠĠĠ Ġconn . do Input Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġreturn Ġdownloaded Bytes ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġdownload File ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠ Ġfile URL : ĠString , ĊĠĠĠĠĠĠĠ Ġsaved Dir : ĠString , ĊĠĠĠĠĠĠĠ Ġ_ filename : ĠString ?, ĊĠĠĠĠĠĠĠ Ġheaders : ĠString , ĊĠĠĠĠĠĠĠ Ġis Resume : ĠBoolean ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġfilename Ġ= Ġ_ filename ĊĠĠĠĠĠĠĠ Ġvar Ġurl Ġ= Ġfile URL ĊĠĠĠĠĠĠĠ Ġvar Ġresource Url : ĠURL ĊĠĠĠĠĠĠĠ Ġvar Ġbase : ĠURL ĊĠĠĠĠĠĠĠ Ġvar Ġnext : ĠURL ĊĠĠĠĠĠĠĠ Ġval Ġvisited : ĠMutable Map < String , ĠInt > ĊĠĠĠĠĠĠĠ Ġvar Ġhttp Conn : ĠHttp URLConnection ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar ĠinputStream : ĠInputStream ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar ĠoutputStream : ĠOutputStream ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġlocation : ĠString ĊĠĠĠĠĠĠĠ Ġvar Ġdownloaded Bytes : ĠLong Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġresponse Code : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġtimes : ĠInt ĊĠĠĠĠĠĠĠ Ġvisited Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhandle Ġred irection Ġlogic ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! visited . containsKey ( url )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimes Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvisited [ url ] Ġ= Ġtimes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimes Ġ= Ġvisited [ url ] !! Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( times Ġ> Ġ 3 ) Ġthrow ĠIOException (" St uck Ġin Ġredirect Ġloop ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresource Url Ġ= ĠURL ( url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Open Ġconnection Ġto Ġ$ url ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn Ġ= Ġresource Url . open Connection () Ġas ĠHttp URLConnection ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn . connect Timeout Ġ= Ġ 1 5 0 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn . read Timeout Ġ= Ġ 1 5 0 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn . instance Follow Redirect s Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ// ĠMake Ġthe Ġlogic Ġbelow Ġeasier Ġto Ġdetect Ġred irection s ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn . setRequest Property (" User - Agent ", Ġ" Mozilla / 5 . 0 ...") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsetup Ġrequest Ġheaders Ġif Ġit Ġis Ġset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Headers ( http Conn , Ġheaders ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtry Ġto Ġcontinue Ġdownloading Ġa Ġfile Ġfrom Ġits Ġpartial Ġdownloaded Ġdata . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Resume ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownloaded Bytes Ġ= Ġsetup Partial Downloaded Data Header ( http Conn , Ġfilename , Ġsaved Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Code Ġ= Ġhttp Conn . response Code ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( response Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHttp URLConnection . HTTP _ MOVED _ PERM , ĠHttp URLConnection . HTTP _ SE E _ OTHER , ĠHttp URLConnection . HTTP _ MOVED _ TEMP , Ġ 3 0 7 , Ġ 3 0 8 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Response Ġwith Ġred irection Ġcode ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Ġ= Ġhttp Conn . getHeader Field (" Location ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Location Ġ= Ġ$ location ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbase Ġ= ĠURL ( url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Ġ= ĠURL ( base , Ġlocation ) Ġ// ĠDe al Ġwith Ġrelative ĠURLs ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġurl Ġ= Ġnext . to External Form () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" New Ġurl : Ġ$ url ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn !!. connect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠcontentType : ĠString ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(( response Code Ġ== ĠHttp URLConnection . HTTP _ OK Ġ|| Ġis Resume Ġ&& Ġresponse Code Ġ== ĠHttp URLConnection . HTTP _ PAR TIAL ) Ġ&& Ġ! is Stopped ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠcontentType Ġ= Ġhttp Conn . contentType ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Length Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . N ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn . content Length Long ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn . content Length ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Content - Type Ġ= Ġ$ contentType ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Content - Length Ġ= Ġ$ content Length ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcharset Ġ= Ġget Charset From ContentType ( contentType ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Charset Ġ= Ġ$ charset ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Resume ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtry Ġto Ġextract Ġfilename Ġfrom ĠHTTP Ġheaders Ġif Ġit Ġis Ġnot Ġgiven Ġby Ġuser ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( filename Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdis position Ġ= Ġhttp Conn . getHeader Field (" Content - Disposition ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Content - Disposition Ġ= Ġ$ dis position ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( dis position Ġ!= Ġnull Ġ&& Ġ! dis position . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilename Ġ= Ġget FileName From Content Disposition ( dis position , Ġcharset ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( filename Ġ== Ġnull Ġ|| Ġfilename . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilename Ġ= Ġurl . substring ( url . lastIndexOf ("/") Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilename Ġ= ĠURL Decoder . decode ( filename , Ġ" UTF - 8 ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* Ġok , Ġjust Ġlet Ġfilename Ġbe Ġnot Ġencoded Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" fileName Ġ= Ġ$ filename ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), Ġfilename , ĠcontentType ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġopens Ġinput Ġstream Ġfrom Ġthe ĠHTTP Ġconnection ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream Ġ= Ġhttp Conn . inputStream ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsaved FilePath : ĠString ? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġopens Ġan Ġoutput Ġstream Ġto Ġsave Ġinto Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthere Ġare Ġtwo Ġcase : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Resume ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 1 . Ġcontinue Ġdownloading Ġ( append Ġdata Ġto Ġpartial Ġdownloaded Ġfile ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsaved FilePath Ġ= Ġsaved Dir Ġ+ ĠFile . separator Ġ+ Ġfilename ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream Ġ= ĠFileOutputStream ( saved FilePath , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 2 . Ġnew Ġdownload , Ġcreate Ġnew Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthere Ġare Ġtwo Ġcase Ġaccording Ġto ĠAndroid ĠSDK Ġversion Ġand Ġsave Ġpath ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFrom ĠAndroid Ġ 1 1 Ġon wards , Ġfile Ġis Ġonly Ġdownloaded Ġto Ġapp - specific Ġdirectory Ġ( internal Ġstorage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġor Ġpublic Ġshared Ġdownload Ġdirectory Ġ( external Ġstorage ). ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġsecond Ġoption Ġwill Ġignore Ġ` saved Dir ` Ġparameter . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . Q Ġ&& Ġsave In Public Storage ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuri Ġ= Ġcreate File In Public Downloads Dir ( filename , ĠcontentType ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsaved FilePath Ġ= Ġget Media Store Entry Path Api 2 9 ( uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream Ġ= Ġcontext . content Resolver . open OutputStream ( uri !! , Ġ" w ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġcreate File In App Specific Dir ( filename , Ġsaved Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsaved FilePath Ġ= Ġfile !!. path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream Ġ= ĠFileOutputStream ( file , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcount Ġ= Ġdownloaded Bytes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbytes Read Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġusing Ġis Stopped () Ġto Ġmonitor Ġcancel ing Ġtask ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( inputStream . read ( buffer ). also Ġ{ Ġbytes Read Ġ= Ġit Ġ} Ġ!= Ġ- 1 Ġ&& Ġ! is Stopped ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcount Ġ+= Ġbytes Read . to Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprogress Ġ= Ġ( count Ġ* Ġ 1 0 0 Ġ/ Ġ( content Length Ġ+ Ġdownloaded Bytes )). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream !!. write ( buffer , Ġ 0 , Ġbytes Read ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(( last Progress Ġ== Ġ 0 Ġ|| Ġprogress Ġ> Ġlast Progress Ġ+ ĠSTEP _ UPDATE Ġ|| Ġprogress Ġ== Ġ 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġprogress Ġ!= Ġlast Progress ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Progress Ġ= Ġprogress ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġline Ġpossibly Ġcauses Ġsystem Ġover loaded Ġbecause Ġof Ġaccessing Ġto ĠDB Ġtoo Ġmany Ġ? !!! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbut Ġcomment ing Ġthis Ġline Ġcauses Ġtasks Ġloaded Ġfrom ĠDB Ġmissing Ġcurrent Ġdownloading Ġprogress , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhowever , Ġthis Ġmissing Ġdata Ġshould Ġbe Ġtemporary Ġand Ġit Ġwill Ġbe Ġupdated Ġas Ġsoon Ġas ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġa Ġnew Ġbunch Ġof Ġdata Ġfetched Ġand Ġa Ġnotification Ġsent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), ĠDownload Status . RUNNING , Ġprogress ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Notification ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilename , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDownload Status . RUNNING , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtask : ĠDownload Task ? Ġ= Ġtask Dao ?. load Task ( id . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprogress Ġ= Ġif Ġ( is Stopped Ġ&& Ġtask ?. res um able Ġ== Ġtrue ) Ġlast Progress Ġelse Ġ 1 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatus : ĠInt Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Stopped ) Ġif Ġ( task ?. res um able Ġ== Ġtrue ) ĠDownload Status . PA USED Ġelse ĠDownload Status . C ANCE LED Ġelse ĠDownload Status . COMPLETE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstorage Ġ= ĠContext Compat . check Self Permission ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠManifest . permission . WRITE _ EXTERNAL _ STORAGE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpending Intent : ĠPending Intent ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( status Ġ== ĠDownload Status . COMPLETE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ< ĠBuild . VERSION _ CODES . Q ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Image Or Video File ( contentType ) Ġ&& Ġis External Storage Path ( saved FilePath )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Image Or Video To Gallery ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilename , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsaved FilePath , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget ContentType Without Charset ( contentType ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( click To Open Downloaded File ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ< ĠBuild . VERSION _ CODES . Q Ġ&& Ġstorage Ġ!= ĠPackage Manager . PERMISSION _ GRAN TED ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent : ĠIntent ? Ġ= ĠIntent Utils . validated File Intent ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsaved FilePath , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠcontentType ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( intent Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Setting Ġan Ġintent Ġto Ġopen Ġthe Ġfile Ġ$ saved FilePath ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflags Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . S ) ĠPending Intent . FLAG _ CANCEL _ CURRENT Ġor ĠPending Intent . FLAG _ IM MUT ABLE Ġelse ĠPending Intent . FLAG _ CANCEL _ CURRENT ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpending Intent Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPending Intent . getActivity ( application Context , Ġ 0 , Ġintent , Ġflags ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" There 's Ġno Ġapplication Ġthat Ġcan Ġopen Ġthe Ġfile Ġ$ saved FilePath ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), Ġstatus , Ġprogress ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Notification ( context , Ġfilename , Ġstatus , Ġprogress , Ġpending Intent , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog ( if Ġ( is Stopped ) Ġ" Download Ġcanceled " Ġelse Ġ" File Ġdownloaded ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtask : ĠDownload Task ? Ġ= Ġtask Dao ?. load Task ( id . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatus : ĠInt Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Stopped ) Ġif Ġ( task ?. res um able Ġ== Ġtrue ) ĠDownload Status . PA USED Ġelse ĠDownload Status . C ANCE LED Ġelse ĠDownload Status . FAILED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), Ġstatus , Ġlast Progress ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Notification ( context , Ġfilename Ġ?: Ġfile URL , Ġstatus , Ġ- 1 , Ġnull , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog ( if Ġ( is Stopped ) Ġ" Download Ġcanceled " Ġelse Ġ" Server Ġrep lied ĠHTTP Ġcode : Ġ$ response Code ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtask Dao ?. update Task ( id . toString (), ĠDownload Status . FAILED , Ġlast Progress ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Notification ( context , Ġfilename Ġ?: Ġfile URL , ĠDownload Status . FAILED , Ġ- 1 , Ġnull , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output Stream Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . flush () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( inputStream Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Conn ?. disconnect () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġa Ġfile Ġusing Ġjava . io ĠAPI ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcreate File In App Specific Dir ( filename : ĠString ?, Ġsaved Dir : ĠString ): ĠFile ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnew File Ġ= ĠFile ( saved Dir , Ġfilename ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrs Ġ= Ġnew File . createNew File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( rs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnew File ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog Error (" It Ġlooks Ġlike Ġyou Ġare Ġtrying Ġto Ġsave Ġfile Ġin Ġpublic Ġstorage Ġbut Ġnot Ġsetting Ġ' save In Public Storage ' Ġto Ġ' true '") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Error (" Create Ġa Ġfile Ġusing Ġjava . io ĠAPI Ġfailed Ġ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġa Ġfile Ġinside Ġthe ĠDownload Ġfolder Ġusing ĠMedia Store ĠAPI ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Requires Api ( Build . VERSION _ CODES . Q ) ĊĠĠĠ Ġprivate Ġfun Ġcreate File In Public Downloads Dir ( filename : ĠString ?, ĠmimeType : ĠString ): ĠUri ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcollection Ġ= ĠMedia Store . Downloads . EXTERNAL _ CONTENT _ URI ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠContent Values () ĊĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Downloads . DISPLAY _ NAME , Ġfilename ) ĊĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Downloads . MIME _ TYPE , ĠmimeType ) ĊĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Downloads . REL ATIVE _ PATH , ĠEnvironment . DIRECTORY _ DOWNLOAD S ) ĊĠĠĠĠĠĠĠ Ġval Ġcontent Resolver : ĠContent Resolver Ġ= Ġapplication Context . content Resolver ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcontent Resolver . insert ( collection , Ġvalues ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Error (" Create Ġa Ġfile Ġusing ĠMedia Store ĠAPI Ġfailed .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġa Ġpath Ġfor Ġa ĠMedia Store Ġentry Ġas Ġit 's Ġneeded Ġwhen Ġcalling ĠMedia Scanner ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Media Store Entry Path Api 2 9 ( uri : ĠUri ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuri ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context . content Resolver . query ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit , ĠarrayOf ( Media Store . Files . File Columns . DATA ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). use Ġ{ Ġcursor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cursor Ġ== Ġnull ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ(! cursor . moveTo First ()) Ġnull Ġelse Ġcursor . getString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor . getColumnIndex OrThrow ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Store . Files . File Columns . DATA ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Error (" Get Ġa Ġpath Ġfor Ġa ĠMedia Store Ġfailed ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġscan FilePath ( path : ĠString , ĠmimeType : ĠString , Ġcallback : ĠCallback Uri ) Ġ{ ĊĠĠĠĠĠĠĠ ĠMedia Scanner Connection . scan File ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context , ĠarrayOf ( path ), ĠarrayOf ( mime Type ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġpath 1 : ĠString ?, Ġuri : ĠUri ? Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . invoke ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuri ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclean Up () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtask : ĠDownload Task ? Ġ= Ġtask Dao ?. load Task ( id . toString ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( task Ġ!= Ġnull Ġ&& Ġtask . status Ġ!= ĠDownload Status . COMPLETE Ġ&& Ġ! task . res um able ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfilename : ĠString Ġ= Ġtask . filename ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġand Ġdelete Ġun completed Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsave FilePath : ĠString Ġ= Ġtask . saved Dir Ġ+ ĠFile . separator Ġ+ Ġfilename ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtemp File Ġ= ĠFile ( save FilePath ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( temp File . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemp File . delete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġnotification Icon Res : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġapplication Info : ĠApplication Info Ġ= Ġapplication Context . package Manager ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. getApplication Info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context . packageName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPackage Manager . GET _ META _ DATA ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġapp Icon Res Id Ġ= Ġapplication Info . icon ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġapplication Info . metaData . getInt ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" vn . hun gh d . flutter downloader . NOTIFICATION _ ICON ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Icon Res Id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠPackage Manager . Name NotFoundException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Notification ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! show Notification ) Ġreturn ĊĠĠĠĠĠĠĠ Ġ// ĠMake Ġa Ġchannel Ġif Ġnecessary ĊĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . O ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCreate Ġthe ĠNotification Channel , Ġbut Ġonly Ġon ĠAPI Ġ 2 6 + Ġbecause ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe ĠNotification Channel Ġclass Ġis Ġnew Ġand Ġnot Ġin Ġthe Ġsupport Ġlibrary ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres : ĠResources Ġ= Ġapplication Context . resources ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchannel Name Ġ= Ġres . getString ( R . string . flutter _ downloader _ notification _ channel _ name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchannel Description Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġres . getString ( R . string . flutter _ downloader _ notification _ channel _ description ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimportance Ġ= ĠNotification Manager . IMPORT ANCE _ LOW ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= ĠNotification Channel ( CHANNEL _ ID , Ġchannel Name , Ġimportance ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . description Ġ= Ġchannel Description ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . set Sound ( null , Ġnull ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdd Ġthe Ġchannel ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnotification Manager Ġ= ĠNotification Manager Compat . from ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotification Manager . create Notification Channel ( channel ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Notification ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠ Ġtitle : ĠString ?, ĊĠĠĠĠĠĠĠ Ġstatus : ĠInt , ĊĠĠĠĠĠĠĠ Ġprogress : ĠInt , ĊĠĠĠĠĠĠĠ Ġintent : ĠPending Intent ?, ĊĠĠĠĠĠĠĠ Ġfinalize : ĠBoolean ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsend Update Process Event ( status , Ġprogress ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠShow Ġthe Ġnotification ĊĠĠĠĠĠĠĠ Ġif Ġ( show Notification ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCreate Ġthe Ġnotification ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= ĠNotification Compat . Builder ( context , ĠCHAN NEL _ ID ). setContent Title ( title ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Intent ( intent ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Only Alert Once ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setAuto Cancel ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Priority ( Notification Compat . PRIORITY _ LOW ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( status Ġ== ĠDownload Status . RUNNING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress Ġ<= Ġ 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Text ( msg Started ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Progress ( 0 , Ġ 0 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . set O ngo ing ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Small Icon ( notification Icon Res ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress Ġ< Ġ 1 0 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Text ( msg InProgress ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Progress ( 1 0 0 , Ġprogress , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// builder . set O ngo ing ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġ. set Small Icon ( R . drawable . stat _ sys _ download ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Text ( msg Complete ). set Progress ( 0 , Ġ 0 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// builder . set O ngo ing ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġ. set Small Icon ( R . drawable . stat _ sys _ download _ done ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( status Ġ== ĠDownload Status . C ANCE LED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Text ( msg Canceled ). set Progress ( 0 , Ġ 0 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// builder . set O ngo ing ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġ. set Small Icon ( R . drawable . stat _ sys _ download _ done ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( status Ġ== ĠDownload Status . FAILED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Text ( msg Failed ). set Progress ( 0 , Ġ 0 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// builder . set O ngo ing ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġ. set Small Icon ( R . drawable . stat _ sys _ download _ done ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( status Ġ== ĠDownload Status . PA USED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Text ( msg Paused ). set Progress ( 0 , Ġ 0 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// builder . set O ngo ing ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġ. set Small Icon ( R . drawable . stat _ sys _ download _ done ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( status Ġ== ĠDownload Status . COMPLETE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Text ( msg Complete ). set Progress ( 0 , Ġ 0 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// builder . set O ngo ing ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġ. set Small Icon ( R . drawable . stat _ sys _ download _ done ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . set Progress ( 0 , Ġ 0 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . set O ngo ing ( false ). set Small Icon ( notification Icon Res ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNote : ĠAndroid Ġapplies Ġa Ġrate Ġlimit Ġwhen Ġupdating Ġa Ġnotification . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġyou Ġpost Ġupdates Ġto Ġa Ġnotification Ġtoo Ġfrequently Ġ( many Ġin Ġless Ġthan Ġone Ġsecond ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġsystem Ġmight Ġdrop Ġsome Ġupdates . Ġ( https :// developer . android . com / training / notify - user / build - notification # Updating ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthis Ġis Ġprogress Ġupdate , Ġit 's Ġnot Ġmuch Ġimportant Ġif Ġit Ġis Ġdropped Ġbecause Ġthere 're Ġstill Ġincoming Ġupdates Ġlater ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthis Ġis Ġthe Ġfinal Ġupdate , Ġit Ġmust Ġbe Ġsuccess Ġotherwise Ġthe Ġnotification Ġwill Ġbe Ġstuck Ġat Ġthe Ġprocessing Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġorder Ġto Ġensure Ġthe Ġfinal Ġone Ġis Ġsuccess , Ġwe Ġcheck Ġand Ġsleep Ġa Ġsecond Ġif Ġneed . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( System . currentTimeMillis () Ġ- Ġlast Call Update Notification Ġ< Ġ 1 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( finalize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Update Ġtoo Ġfrequently !!!! , Ġbut Ġit Ġis Ġthe Ġfinal Ġupdate , Ġwe Ġshould Ġsleep Ġa Ġsecond Ġto Ġensure Ġthe Ġupdate Ġcall Ġcan Ġbe Ġprocessed ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( 1 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Update Ġtoo Ġfrequently !!!! , Ġthis Ġshould Ġbe Ġdropped ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Update Ġnotification : Ġ{ notification Id : Ġ$ primary Id , Ġtitle : Ġ$ title , Ġstatus : Ġ$ status , Ġprogress : Ġ$ progress }") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNotification Manager Compat . from ( context ). notify ( primary Id , Ġbuilder . build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Call Update Notification Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Update Process Event ( status : ĠInt , Ġprogress : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġargs : ĠMutable List < Any > Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠ Ġval Ġcallback Handle : ĠLong Ġ= Ġinput Data . getLong ( ARG _ CALLBACK _ HANDLE , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġargs . add ( callback Handle ) ĊĠĠĠĠĠĠĠ Ġargs . add ( id . toString ()) ĊĠĠĠĠĠĠĠ Ġargs . add ( status ) ĊĠĠĠĠĠĠĠ Ġargs . add ( progress ) ĊĠĠĠĠĠĠĠ Ġsynchronized ( isolate Started ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! isolate Started . get ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġisolate Queue . add ( args ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHandler ( application Context . main Looper ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. post ( Runnable Ġ{ Ġbackground Channel ?. invoke Method ("", Ġargs ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Charset From ContentType ( contentType : ĠString ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( contentType Ġ== Ġnull ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġm Ġ= Ġcharset Pattern . matcher ( contentType ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( m . find ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġunsafe Ġto Ġuse Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm . group ( 1 ). trim Ġ{ Ġit Ġ<= Ġ' Ġ' Ġ}. uppercase ( Locale . getDefault ()) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Unsupported EncodingException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġget FileName From Content Disposition ( ĊĠĠĠĠĠĠĠ Ġdis position : ĠString ?, ĊĠĠĠĠĠĠĠ Ġcontent Charset : ĠString ? ĊĠĠĠ Ġ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( dis position Ġ== Ġnull ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġname : ĠString ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġcharset Ġ= Ġcontent Charset ĊĊĠĠĠĠĠĠĠ Ġ// first , Ġmatch Ġplain Ġfilename , Ġand Ġthen Ġreplace Ġit Ġwith Ġstar Ġfilename , Ġto Ġfollow Ġthe Ġspec ĊĠĠĠĠĠĠĠ Ġval Ġplain Matcher Ġ= Ġfilename Pattern . matcher ( dis position ) ĊĠĠĠĠĠĠĠ Ġif Ġ( plain Matcher . find ()) Ġname Ġ= Ġplain Matcher . group ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġstar Matcher Ġ= Ġfilename Star Pattern . matcher ( dis position ) ĊĠĠĠĠĠĠĠ Ġif Ġ( star Matcher . find ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġstar Matcher . group ( 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġunsafe Ġto Ġuse Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcharset Ġ= Ġstar Matcher . group ( 1 ). uppercase ( Locale . getDefault ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( name Ġ== Ġnull ) Ġnull Ġelse ĠURL Decoder . decode ( name , Ġcharset Ġ?: Ġ" ISO - 8 8 5 9 - 1 ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget ContentType Without Charset ( contentType : ĠString ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠcontentType ?. split ("; ") ?. to Typed Array ()?. get ( 0 )?. trim Ġ{ Ġit Ġ<= Ġ' Ġ' Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Image Or Video File (_ contentType : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġvar ĠcontentType : ĠString ? Ġ= Ġ_ contentType ĊĠĠĠĠĠĠĠ ĠcontentType Ġ= Ġget ContentType Without Charset ( contentType ) ĊĠĠĠĠĠĠĠ Ġreturn ĠcontentType Ġ!= Ġnull Ġ&& Ġ( contentType . startsWith (" image /") Ġ|| ĠcontentType . startsWith (" video ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis External Storage Path ( filePath : ĠString ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexternal Storage Dir Ġ= ĠEnvironment . get External Storage Directory () ĊĠĠĠĠĠĠĠ Ġreturn ĠfilePath Ġ!= Ġnull Ġ&& Ġexternal Storage Dir Ġ!= Ġnull Ġ&& ĠfilePath . startsWith ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexternal Storage Dir . path ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Image Or Video To Gallery ( ĊĠĠĠĠĠĠĠ ĠfileName : ĠString ?, ĊĠĠĠĠĠĠĠ ĠfilePath : ĠString ?, ĊĠĠĠĠĠĠĠ ĠcontentType : ĠString ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( contentType Ġ!= Ġnull Ġ&& ĠfilePath Ġ!= Ġnull Ġ&& ĠfileName Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( contentType . startsWith (" image / ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠContent Values () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Images . Media . TITLE , ĠfileName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Images . Media . DISPLAY _ NAME , ĠfileName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Images . Media . DESCRIPTION , Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Images . Media . MIME _ TYPE , ĠcontentType ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Images . Media . DATE _ AD DED , ĠSystem . currentTimeMillis ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Images . Media . DATE _ TA KEN , ĠSystem . currentTimeMillis ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Images . Media . DATA , ĠfilePath ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" insert Ġ$ values Ġto ĠMedia Store ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Resolver : ĠContent Resolver Ġ= Ġapplication Context . content Resolver ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Resolver . insert ( Media Store . Images . Media . EXTERNAL _ CONTENT _ URI , Ġvalues ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( contentType . startsWith (" video ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠContent Values () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Video . Media . TITLE , ĠfileName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Video . Media . DISPLAY _ NAME , ĠfileName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Video . Media . DESCRIPTION , Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Video . Media . MIME _ TYPE , ĠcontentType ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Video . Media . DATE _ AD DED , ĠSystem . currentTimeMillis ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Video . Media . DATE _ TA KEN , ĠSystem . currentTimeMillis ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . put ( Media Store . Video . Media . DATA , ĠfilePath ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" insert Ġ$ values Ġto ĠMedia Store ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Resolver : ĠContent Resolver Ġ= Ġapplication Context . content Resolver ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Resolver . insert ( Media Store . Video . Media . EXTERNAL _ CONTENT _ URI , Ġvalues ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlog ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( debug ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġmessage ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlog Error ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( debug ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġmessage ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠCallback Uri Ġ{ ĊĠĠĠĠĠĠĠ Ġoperator Ġfun Ġinvoke ( uri : ĠUri ?) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ URL Ġ= Ġ" url " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ FILE _ NAME Ġ= Ġ" file _ name " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ SA VED _ DIR Ġ= Ġ" saved _ file " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ HEADERS Ġ= Ġ" headers " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ IS _ RE SU ME Ġ= Ġ" is _ resume " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ SHOW _ NOTIFICATION Ġ= Ġ" show _ notification " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ OPEN _ FILE _ FROM _ NOTIFICATION Ġ= Ġ" open _ file _ from _ notification " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ CALLBACK _ HANDLE Ġ= Ġ" callback _ handle " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ DEBUG Ġ= Ġ" debug " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠARG _ SAVE _ IN _ PUBLIC _ STORAGE Ġ= Ġ" save _ in _ public _ storage " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠTAG Ġ= ĠDownload Worker :: class . java . simple Name ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠBUFFER _ SIZE Ġ= Ġ 4 0 9 6 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCHAN NEL _ ID Ġ= Ġ" FL UT TER _ DOWNLOAD ER _ NOTIFICATION " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠSTEP _ UPDATE Ġ= Ġ 5 ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġisolate Started Ġ= ĠAtomic Boolean ( false ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġisolate Queue Ġ= ĠArray Deque < List <* >>() ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġbackground Flutter Engine : ĠFlutter Engine ? Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ ĠHandler ( context . main Looper ). post Ġ{ Ġstart Background Is olate ( context ) Ġ} ĊĠĠĠ Ġ} Ċ }