package Ġlink . stand en . m ichael . phones aver . sa ver Ċ Ċ import Ġandroid . app . Download Manager Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . media . Media Scanner Connection Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . AsyncTask Ċ import Ġandroid . webkit . MimeType Map Ċ import Ġlink . stand en . m ichael . phones aver . R Ċ import Ġlink . stand en . m ichael . phones aver . activity . Saver Activity Ċ import Ġlink . stand en . m ichael . phones aver . data . Connection Pair Ċ import Ġlink . stand en . m ichael . phones aver . data . Pair Ċ import Ġlink . stand en . m ichael . phones aver . util .* Ċ import Ġjava . io .* Ċ import Ġjava . lang . ref . Weak Reference Ċ import Ġjava . net . Http URLConnection Ċ import Ġjava . net . Malformed URLException Ċ import Ġjava . net . URL Ċ Ċ /** Ċ Ġ* ĠAn Ġasync Ġtask Ġto Ġhandle Ġsaving Ġa Ġsingle Ġtext Ġentry Ċ Ġ*/ Ċ class ĠHandle Single Text Task Ċ internal Ġconstructor ( Ċĉ ĉ context : ĠS aver Activity , Ċĉ ĉ private Ġval Ġtext : ĠString , Ċĉ ĉ private Ġval Ġintent : ĠIntent , Ċĉ ĉ private Ġval Ġdry Run : ĠBoolean , Ċĉ ĉ private Ġval Ġcallback : Ġ( success : ĠBoolean ?) Ġ-> ĠUnit ) Ċ ĉ : ĠAsync Task < Unit , ĠUnit , ĠUnit >() Ġ{ ĊĊ ĉ private Ġval Ġsa ver Activity Ref : ĠWeak Reference < Saver Activity > Ġ= ĠWeak Reference ( context ) ĊĊ ĉ private Ġlateinit Ġvar Ġlog : ĠDebug Logger ĊĊ ĉ override Ġfun Ġdo In Background ( var arg Ġparams : ĠUnit ?) Ġ{ Ċĉ ĉ val Ġsa ver Activity Ġ= Ġsa ver Activity Ref . get () ĊĊĉ ĉ if Ġ( sa ver Activity Ġ== Ġnull Ġ|| Ġsa ver Activity . is Finish ing ){ Ċĉĉ ĉ callback ( false ) Ċĉĉ ĉ return Ċĉ ĉ } Ċĉ ĉ log Ġ= ĠDebug Logger ( sa ver Activity , ĠHandle Single Text Task :: class . java . simple Name ) ĊĊĉ ĉ try Ġ{ Ċĉĉ ĉ // ĠUse Ġexception Ġto Ġtest Ċĉĉ ĉ URL ( text ) Ċĉĉ ĉ // ĠIt 's Ġa ĠURL Ċĉĉ ĉ log . d (" Text Ġwith ĠURL ") Ċĉĉ ĉ var Ġpair Ġ= ĠConnection Pair ( text , Ġnull ) Ċĉĉ ĉ if Ġ( Preference Helper . follow Redirect s ) Ġ{ Ċĉĉĉ ĉ // ĠFollow Ġredirects Ċĉĉĉ ĉ pair Ġ= ĠLink Helper . resolve Redirect s ( sa ver Activity , Ġpair . url ) Ċĉĉ ĉ } Ċĉĉ ĉ if Ġ( Preference Helper . special Img ur ){ Ċĉĉĉ ĉ // ĠConvert Ġimg ur ĠURL Ġto Ġimg ur Ċĉĉĉ ĉ pair Ġ= ĠImg ur Helper . getImage Url ( sa ver Activity , Ġpair ) Ċĉĉ ĉ } ĊĊĉĉ ĉ // ĠDefault Ġto Ġopen Ġconnection Ġcontent Ġtype Ċĉĉ ĉ var Ġurl ContentType : ĠString ? Ġ= Ġpair . conn ?. getHeader Field (" Content - Type ") Ċĉĉ ĉ if Ġ( url ContentType Ġ== Ġnull ) Ġ{ Ċĉĉĉ ĉ // ĠSecond Ġtry ĠURL Ġmime Ċĉĉĉ ĉ url ContentType Ġ= ĠMime TypeMap . get Singleton (). get MimeType From Extension ( MimeType Map . getFile Extension From Url ( pair . url )) Ċĉĉ ĉ } Ċĉĉ ĉ if Ġ( url ContentType Ġ== Ġnull Ġ&& Ġpair . conn Ġ== Ġnull ){ Ċĉĉĉ ĉ // ĠFall Ġback Ġto Ġchecking ĠURL Ġcontent Ġtype Ċĉĉĉ ĉ pair Ġ= ĠConnection Pair ( pair . url , ĠURL ( pair . url ). open Connection () Ġas ĠHttp URLConnection ) Ċĉĉĉ ĉ url ContentType Ġ= Ġpair . conn ?. getHeader Field (" Content - Type ") Ċĉĉ ĉ } Ċĉĉ ĉ if Ġ( pair . conn Ġis ĠHttp URLConnection ){ Ċĉĉĉ ĉ // ĠWe Ġare Ġdone Ġwith Ġthe Ġconnection Ċĉĉĉ ĉ with Ġ( pair . conn Ġas ĠHttp URLConnection ){ Ċĉĉĉĉ ĉ this . disconnect () Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊĉĉ ĉ url ContentType ?. toLowerCase ()?. let Ġ{ ĠcontentType Ġ-> Ċĉĉĉ ĉ log . d (" URL ĠContent - Type : Ġ$ contentType ") Ċĉĉĉ ĉ sa ver Activity . debug Info . add ( Pair (" URL ĠContent - Type ", ĠcontentType )) Ċĉĉĉ ĉ val Ġuri Ġ= ĠUri . parse ( pair . url ) Ċĉĉĉ ĉ sa ver Activity . get Filename ( intent . getString Extra ( Intent . EXTRA _ SUBJECT ) Ġ?: Ġuri . last Path Segment Ġ?: Ġ" default ", Ċĉĉĉĉĉ ĉ contentType , Ġdry Run , Ġ{ Ġfilename Ġ-> Ċĉĉĉĉ ĉ if Ġ( contentType . startsWith (" image /") Ġ|| Ċĉĉĉĉĉĉ ĉ contentType . startsWith (" video /") Ġ|| Ċĉĉĉĉĉĉ ĉ contentType . startsWith (" audio / ")) Ġ{ Ċĉĉĉĉĉ ĉ save Url ( sa ver Activity , Ġuri , Ġfilename , Ġcallback , Ġdry Run ) Ċĉĉĉĉ ĉ } Ġelse Ġif Ġ( contentType . startsWith (" text / ")){ Ċĉĉĉĉĉ ĉ save String ( sa ver Activity , Ġpair . url , Ġfilename , Ġcallback , Ġdry Run ) Ċĉĉĉĉ ĉ } Ġelse Ġif Ġ( Preference Helper . force Saving Ġ&& Ġ! dry Run ){ Ċĉĉĉĉĉ ĉ // ĠF allback Ġto Ġsaving Ġwith Ġsave Url Ċĉĉĉĉĉ ĉ save Url ( sa ver Activity , Ġuri , Ġfilename , Ġcallback , Ġdry Run ) Ċĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉ ĉ callback ( false ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ }) Ċĉĉ ĉ } ?: Ġcallback ( false ) Ċĉ ĉ } Ġcatch Ġ( e : ĠMal formed URLException ){ Ċĉĉ ĉ log . d (" Text Ġwithout ĠURL ") Ċĉĉ ĉ // ĠIt 's Ġjust Ġsome Ġtext Ċĉĉ ĉ val ĠmimeType : ĠString Ġ= Ġintent . type ?. toLowerCase () Ġ?: Ġ" text / plain " Ċĉĉ ĉ sa ver Activity . get Filename ( intent . getString Extra ( Intent . EXTRA _ SUBJECT ) Ġ?: Ġtext , Ċĉĉĉĉ ĉ mime Type , Ġdry Run , Ġ{ Ġfilename Ġ-> Ċĉĉĉ ĉ save String ( sa ver Activity , Ġtext , Ġfilename , Ġcallback , Ġdry Run ) Ċĉĉ ĉ }) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠSave Ġthe Ġgiven Ġurl Ġto Ġthe Ġfilesystem Ċĉ Ġ*/ Ċ ĉ private Ġfun Ġsave Url ( sa ver Activity : ĠS aver Activity , Ġuri : ĠUri , Ġfilename : ĠString , Ġcallback : Ġ( success : ĠBoolean ?) Ġ-> ĠUnit , Ġdry Run : ĠBoolean ) Ġ{ Ċĉ ĉ if Ġ( dry Run ){ Ċĉĉ ĉ // ĠThis Ġentire Ġmethod Ġcan Ġbe Ġskipped Ġwhen Ġdoing Ġa Ġdry Ġrun Ċĉĉ ĉ return Ġcallback ( true ) Ċĉ ĉ } ĊĊĉ ĉ val Ġsource Filename Ġ= Ġuri . toString () ĊĊĉ ĉ if Ġ( sa ver Activity . location Ġ== Ġnull ) Ġ{ Ċĉĉ ĉ // ĠNo Ġlocation , Ġuse Ġdocument UI Ċĉĉ ĉ sa ver Activity . return From Activity Result Ġ= Ġ{ Ġdestination Ġ-> Ċĉĉĉ ĉ if Ġ( destination Ġ== Ġnull ){ Ċĉĉĉĉ ĉ callback ( false ) Ċĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉ ĉ log . d (" Calling Ġto Ġsave ĠURL Ġ$ source Filename Ġto Ġ$ destination ") Ċĉĉĉĉ ĉ Save From Url Task ( sa ver Activity , Ġsource Filename , Ġdestination , Ġfilename , Ġdry Run , Ġcallback ). execute () Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉĉ ĉ Location Select Task ( sa ver Activity ). save ( filename , Ġsa ver Activity . converted Mime !! ) Ċĉ ĉ } Ġelse Ġ{ Ċĉĉ ĉ // ĠLoc ate Ġpassed Ċĉĉ ĉ val Ġdestination Filename Ġ= ĠLocation Helper . safe Add Path ( sa ver Activity . location , Ġfilename ) ĊĊĉĉ ĉ log . d (" Saving Ġ$ source Filename Ġto Ġ$ destination Filename ") ĊĊĉĉ ĉ val Ġdown loader Ġ= ĠDownload Manager . Request ( uri ) Ċĉĉ ĉ downloader . set Allowed Network Types ( Download Manager . Request . NETWORK _ MOB ILE Ġor ĠDownload Manager . Request . NETWORK _ WIFI ) Ċĉĉĉĉ ĉ . set Destination In External Public Dir ( Location Helper . remove Root ( sa ver Activity . location !! ), Ġfilename ) Ċĉĉĉĉ ĉ . set Allowed Over Roaming ( true ) Ċĉĉĉĉ ĉ . setTitle ( filename ) Ċĉĉĉĉ ĉ . setDescription ( sa ver Activity . resources . getString ( R . string . downloader _ description , Ġsource Filename )) ĊĊĉĉ ĉ if Ġ( Preference Helper . register Media Server ){ Ċĉĉĉ ĉ downloader . allow Sc anning By Media Scanner () Ċĉĉ ĉ } ĊĊĉĉ ĉ ( sa ver Activity . getSystem Service ( Context . DOWNLOAD _ SERVICE ) Ġas ĠDownload Manager ). enqueue ( downloader ) ĊĊĉĉ ĉ callback ( null ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠSave Ġa Ġstring Ġto Ġthe Ġfilesystem Ċĉ Ġ*/ Ċ ĉ private Ġfun Ġsave String ( sa ver Activity : ĠS aver Activity , Ġs : ĠString , Ġfilename : ĠString , Ġcallback : Ġ( success : ĠBoolean ?) Ġ-> ĠUnit , Ġdry Run : ĠBoolean ) Ġ{ Ċĉ ĉ if Ġ( dry Run ){ Ċĉĉ ĉ // ĠThis Ġentire Ġmethod Ġcan Ġbe Ġskipped Ġwhen Ġdoing Ġa Ġdry Ġrun Ċĉĉ ĉ return Ġcallback ( true ) Ċĉ ĉ } ĊĊĉ ĉ if Ġ( sa ver Activity . location Ġ== Ġnull ) Ġ{ Ċĉĉ ĉ // ĠNo Ġlocation , Ġuse Ġdocument UI Ċĉĉ ĉ sa ver Activity . return From Activity Result Ġ= Ġ{ Ċĉĉĉ ĉ if Ġ( it Ġ== Ġnull ){ Ċĉĉĉĉ ĉ callback ( false ) Ċĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉ ĉ val Ġp fd Ġ= Ġsa ver Activity . content Resolver . open FileDescriptor ( it , Ġ" w ") Ċĉĉĉĉ ĉ if Ġ( p fd Ġ== Ġnull ){ Ċĉĉĉĉĉ ĉ callback ( false ) Ċĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉ ĉ val Ġb os Ġ= ĠBuffered OutputStream ( File OutputStream ( p fd . file Descriptor )) Ċĉĉĉĉĉ ĉ do Save String ( sa ver Activity , Ġb os , Ġs , Ġnull , Ġcallback ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉĉ ĉ Location Select Task ( sa ver Activity ). save ( filename , Ġsa ver Activity . converted Mime !! ) Ċĉ ĉ } Ġelse Ġ{ Ċĉĉ ĉ // ĠManual Ċĉĉ ĉ val Ġdestination Filename Ġ= ĠLocation Helper . safe Add Path ( sa ver Activity . location , Ġfilename ) Ċĉĉ ĉ var Ġb os : ĠBuffered OutputStream ? Ġ= Ġnull Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ val Ġfout Ġ= ĠFile ( destination Filename ) Ċĉĉĉ ĉ if Ġ(! f out . exists ()){ Ċĉĉĉĉ ĉ f out . createNew File () Ċĉĉĉ ĉ } Ċĉĉĉ ĉ bos Ġ= ĠBuffered OutputStream ( File OutputStream ( destination Filename )) Ċĉĉĉ ĉ do Save String ( sa ver Activity , Ġb os , Ġs , Ġdestination Filename , Ġcallback ) Ċĉĉ ĉ } Ġcatch Ġ( e : ĠIOException ) Ġ{ Ċĉĉĉ ĉ log . e (" Unable Ġto Ġsave Ġfile ", Ġe ) Ċĉĉ ĉ } Ġfinally Ġ{ Ċĉĉĉ ĉ try Ġ{ Ċĉĉĉĉ ĉ bos ?. close () Ċĉĉĉ ĉ } Ġcatch Ġ( e : ĠIOException ) Ġ{ Ċĉĉĉĉ ĉ log . e (" Unable Ġto Ġclose Ġstream ", Ġe ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠDo Ġthe Ġsaving Ġof Ġthe Ġstring Ċĉ Ġ*/ Ċ ĉ private Ġfun Ġdo Save String ( sa ver Activity : ĠS aver Activity , Ġb os : ĠBuffered OutputStream , Ġs : ĠString , Ċĉĉĉĉĉĉĉ Ġdestination Filename : ĠString ?, Ġcallback : Ġ( success : ĠBoolean ?) Ġ-> ĠUnit ){ Ċĉ ĉ var Ġsuccess Ġ= Ġfalse ĊĊĉ ĉ try Ġ{ Ċĉĉ ĉ bos . write ( s . toByteArray ()) ĊĊĉĉ ĉ // ĠDone Ċĉĉ ĉ success Ġ= Ġtrue ĊĊĉĉ ĉ if Ġ( Preference Helper . register Media Server Ġ&& Ġdestination Filename Ġ!= Ġnull ){ Ċĉĉĉ ĉ Media Scanner Connection . scan File ( sa ver Activity , ĠarrayOf ( destination Filename ), Ġnull , Ġnull ) Ċĉĉ ĉ } Ċĉ ĉ } Ġcatch Ġ( e : ĠIOException ) Ġ{ Ċĉĉ ĉ log . e (" Unable Ġto Ġsave Ġfile ", Ġe ) Ċĉ ĉ } Ċĉ ĉ callback ( success ) Ċ ĉ } Ċ } Ċ