package Ġcom . tit an ium . loc getter . main Ċ Ċ import Ġandroid . Manifest Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . app . Activity Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . pm . PackageManager Ċ import Ġandroid . location . Location Ċ import Ġandroid . location . Location Manager Ċ import Ġandroid . os . Build Ċ import Ġandroid . provider . Settings Ċ import Ġandroid . support . v 4 . content . Context Compat Ċ import Ġcodes . tit an ium . connect able activity . launch Connect able Activity Ċ import Ġcom . google . android . gms . common . api . ApiException Ċ import Ġcom . google . android . gms . common . api . Res olvable ApiException Ċ import Ġcom . google . android . gms . location .* Ċ import Ġcom . tit an ium . loc getter . exception . Location Settings Exception Ċ import Ġcom . tit an ium . loc getter . exception . Mock Location Exception Ċ import Ġcom . tit an ium . loc getter . exception . No Location Permission Ċ import Ġio . reactivex . Observable Ċ import Ġio . reactivex . Observable Emitter Ċ import Ġio . reactivex . android . schedul ers . Android Schedulers Ċ import Ġio . reactivex . subjects . Publish Subject Ċ import Ġio . reactivex . subjects . Subject Ċ Ċ internal Ġclass ĠMain Location Getter Ġconstructor ( private Ġval Ġapp Context : ĠContext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġlogger : Ġ(( String , ĠString ) Ġ-> ĠUnit ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġaccept Mock Locations : ĠBoolean ) Ġ: ĠLocation Getter Ġ{ ĊĊĠĠĠ Ġoverride Ġval Ġhot Locations : ĠSubject < Location > Ġ= ĠPublish Subject . create () ĊĠĠĠ Ġprivate Ġvar Ġlatest Location : ĠLocation ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġlocation Request : ĠLocation Request ĊĠĠĠ Ġprivate Ġvar Ġf used Location Provider Client Ġ= ĠLocation Services . getF used Location Provider Client ( app Context ) ĊĠĠĠ Ġprivate Ġval Ġlocation Share : ĠObservable < Location > Ġ= ĠLocation Sn iffer (). start Emit ting Locations (). share () ĊĠĠĠ Ġprivate Ġval Ġsettings Share : ĠObservable < Any > Ġ= Ġget Location Settings Status (). share () ĊĠĠĠ Ġprivate Ġval Ġpermissions Share : ĠObservable < Any > Ġ= Ġcheck Permissions (). share () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġlocation Request Ġ= ĠLocation Request . create () ĊĠĠĠĠĠĠĠ Ġlocation Request . fast est Interval Ġ= Ġ 5 0 0 0 ĊĠĠĠĠĠĠĠ Ġlocation Request . interval Ġ= Ġ 5 0 0 0 ĊĠĠĠĠĠĠĠ Ġlocation Request . priority Ġ= ĠLocation Request . PRIORITY _ HIGH _ AC CUR ACY ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Latest Saved Location () Ġ= Ġlatest Location ĊĊĠĠĠ Ġoverride Ġfun Ġget Latest Locations () Ġ= Ġpermissions Share ĊĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġsettings Share Ġ} ĊĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġlocation Share Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġget Location Settings Status () Ġ= ĠObservable . create < Any > Ġ{ Ġsubscriber Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( is Location Enabled ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onNext ("") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onComplete () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= ĠLocation Settings Request . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Always Show ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Location Request ( location Request ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠLocation Services . get Settings Client ( app Context ). check Location Settings ( builder . build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add On Complete Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . getResult ( ApiException :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onNext ("") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onComplete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠApiException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( exception . statusCode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocation Settings StatusCode s . RESOL UTION _ REQUIRED Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Settings ( subscriber , Ġexception Ġas ĠRes olvable ApiException ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onError ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocation Settings StatusCode s . SETTINGS _ CHANGE _ UN AVAILABLE Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onError ( exception ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Settings ( subscriber : ĠObservable Emitter < Any >, Ġresol vable ApiException : ĠRes olvable ApiException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠonError Ġ= Ġ{ Ġif Ġ(! subscriber . is Disposed ) Ġsubscriber . onError ( Location Settings Exception ()) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġask Request : Ġ( Activity ) Ġ-> ĠUnit Ġ= Ġ{ Ġresol vable ApiException . start Resolution For Result ( it , Ġ 0 ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġask Result : Ġ( Int , ĠIntent ?) Ġ-> ĠUnit Ġ= Ġ{ ĠresultCode , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠActivity . RESULT _ OK Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onNext ("") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubscriber . onComplete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠonError () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġapp Context . launch Connect able Activity ( ask Request , Ġon Activity Result Ġ= Ġask Result , Ġon De Attach Ġ= ĠonError ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress Lint (" New Api ") ĊĠĠĠ Ġprivate Ġfun Ġcheck Permissions () Ġ= ĠObservable . create < Any > Ġ{ Ġemitter Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( is Location Per mitted ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onNext ("") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onComplete () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġperm Request : Ġ( Activity ) Ġ-> ĠUnit Ġ= Ġ{ Ġf Ġ-> Ġf . request Permissions ( array Of ( Manifest . permission . ACCESS _ F INE _ LOCATION ), Ġ 0 ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġon De Attach : Ġ() Ġ-> ĠUnit Ġ= Ġ{ Ġif Ġ(! emitter . is Disposed ) Ġemitter . onError ( RuntimeException (" timeout ")) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġperm Result : Ġ( Boolean ) Ġ-> ĠUnit Ġ= Ġ{ Ġis Granted Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Granted ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onNext ("") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onComplete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onError ( No Location Permission ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapp Context . launch Connect able Activity ( perm Request , Ġon Request Permissions Result Ġ= Ġperm Result , Ġon De Attach Ġ= Ġon De Attach ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Location Per mitted () Ġ= ĠContext Compat . check Self Permission ( app Context , ĠManifest . permission . ACCESS _ F INE _ LOCATION ) Ġ== ĠPackage Manager . PERMISSION _ GRAN TED ĊĊĠĠĠ Ġprivate Ġfun Ġis Location Enabled () Ġ= Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . P ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlm Ġ= Ġapp Context . getSystem Service ( Context . LOCATION _ SERVICE ) Ġas ĠLocation Manager ĊĠĠĠĠĠĠĠ Ġlm . is Location Enabled ĊĠĠĠ Ġ} Ġelse Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . KIT K AT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmode Ġ= ĠSettings . Secure . getInt ( app Context . content Resolver , ĠSettings . Secure . LOCATION _ MODE , ĠSettings . Secure . LOCATION _ MODE _ OFF ) ĊĠĠĠĠĠĠĠ Ġmode Ġ!= ĠSettings . Secure . LOCATION _ MODE _ OFF ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlocation Manager Ġ= Ġapp Context . getSystem Service ( Context . LOCATION _ SERVICE ) Ġas ĠLocation Manager ĊĠĠĠĠĠĠĠ Ġlocation Manager . is Provider Enabled ( Location Manager . NETWORK _ PROVIDER ) Ġ&& Ġlocation Manager . is Provider Enabled ( Location Manager . GPS _ PROVIDER ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinner Ġclass ĠLocation Sn iffer Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġon Location : Ġ(( Location ) Ġ-> ĠUnit )? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġlistener : ĠLocation Callback Ġ= Ġobject Ġ: ĠLocation Callback () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Location Result ( p 0 : ĠLocation Result ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp 0 ?. last Location ?. let Ġ{ Ġon Location ?. invoke ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Suppress Lint (" New Api ") ĊĠĠĠĠĠĠĠ Ġfun Ġstart Emit ting Locations (): ĠObservable < Location > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// wrap Ġcallback Ġwith Ġobservable . create ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠObservable . create Ġ{ Ġe Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Location Ġ= Ġ{ Ġlocation Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// as Ġsoon Ġas Ġit Ġis Ġdisposed Ġ- Ġunsubscribe Ġfrom Ġupdates ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e . is Disposed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun Subscribe From Updates () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( location . is From Mock Provider Ġ&& Ġ! accept Mock Locations ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . onError ( Mock Location Exception ( location )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger ( TAG , Ġ" Got Ġnew Ġlocation Ġ: $ location Ġ, speed Ġ: ${ location . speed }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Location Ġ= Ġlocation ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhot Locations . onNext ( location ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . onNext ( location ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubscribe To Updates () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Suppress Lint (" Missing Permission ") ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġsubscribe To Updates () Ġ= ĠAndroid Schedulers . main Thread (). schedule Direct Ġ{ Ġf used Location Provider Client . request Location Updates ( location Request , Ġlistener , Ġnull ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġun Subscribe From Updates () Ġ= Ġf used Location Provider Client . remove Location Updates ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠTAG Ġ= Ġ" Main Location Getter " ĊĠĠĠ Ġ} Ċ }