package Ġcom . fre el app . location fetcher . compose Ċ Ċ import Ġandroidx . compose . material 3 . AlertDialog Ċ import Ġandroidx . compose . material 3 . Button Ċ import Ġandroidx . compose . material 3 . Text Ċ import Ġandroidx . compose . runtime .* Ċ import Ġandroidx . compose . ui . platform . Local Context Ċ import Ġandroidx . compose . ui . res . string Resource Ċ import Ġcom . google . android . gms . location . Location Request Ċ import Ġcom . google . android . gms . location . Location Result Ċ Ċ /** Ċ Ġ* ĠAn Ġaggregate Ġof Ġthe Ġ[ last Ġlocations ][ location Result ], Ċ Ġ* Ġ[ location Ġsetting Ġstatus ][ setting Enabled ], Ġand Ġ[ permission Ġstatus ][ permissions Granted ], Ġas Ċ Ġ* Ġreported Ġby Ġ[ Location Fetcher ]. Ċ Ġ*/ Ċ @ Immutable Ċ public Ġdata Ġclass ĠLocation State ( ĊĠĠĠ Ġ/** ĠLatest Ġlocation Ġresults , Ġor Ġnull Ġif Ġno Ġlocations Ġwere Ġreported Ġl ately . Ġ*/ ĊĠĠĠ Ġval Ġlocation Result : ĠLocation Result ?, ĊĠĠĠ Ġ/** ĠWhether Ġlocation Ġsetting Ġis Ġenabled , Ġor Ġnull Ġif Ġstatus Ġis Ġunknown . Ġ*/ ĊĠĠĠ Ġval Ġsetting Enabled : ĠBoolean ?, ĊĠĠĠ Ġ/** ĠWhether Ġlocation Ġpermissions Ġare Ġgranted . Ġ*/ ĊĠĠĠ Ġval Ġpermissions Granted : ĠBoolean Ċ ) Ċ Ċ /** Ċ Ġ* ĠObtain Ġperiodic Ġlocation Ġupdates Ġfrom Ġthe Ġdevice . ĠThe Ġ[ Location Result ] Ġis Ġdelivered Ġto Ġall Ċ Ġ* Ġchildren Ġcomp osable Ġby Ġa Ġ[ Composition Local ]: Ġ[ Local Location Fetcher . current ]. Ċ Ġ* Ċ Ġ* Ġ[ Location Request ] Ġconfigurations Ġcan Ġbe Ġset Ġby Ġ[ request Config ]. Ċ Ġ* Ċ Ġ* ĠIf Ġthe Ġlocation Ġpermissions Ġare Ġnot Ġgranted Ġby Ġthe Ġuser , Ġthis Ġ[ Composable ] Ġwill Ġrequest Ġthem Ċ Ġ* Ġto Ġthe Ġuser . ĠIf Ġthe ĠAndroid Ġframework Ġtells Ġthat Ġa Ġ[ ration ale ] Ġfor Ġrequesting Ġthe Ġpermissions Ċ Ġ* Ġmust Ġbe Ġpresented , Ġa Ġ[ Material 3 ĠAlertDialog ][ AlertDialog ] Ġwill Ġbe Ġused . Ċ Ġ* Ċ Ġ* ĠIf Ġyou Ġprefer Ġto Ġuse Ġa Ġcustom Ġ[ Composable ] Ġfor Ġshowing Ġthe Ġ[ ration ale ] Ġinstead , Ġsee Ġthe Ġoverload Ċ Ġ* Ġthat Ġtakes Ġin Ġa Ġr ationale ĠUI Ġinstead Ġof Ġa Ġr ationale ĠString . Ċ Ġ* Ċ Ġ* ĠOnce Ġlocation Ġpermissions Ġare Ġgranted Ġby Ġthe Ġuser , Ġthis Ġ[ Composable ] Ġwill Ġcheck Ġwhether Ġlocation Ċ Ġ* Ġsettings Ġare Ġenabled Ġin Ġthe ĠAndroid Ġsettings , Ġasking Ġthe Ġuser Ġto Ġenable Ġthem Ġin Ġcase Ġthey 're Ċ Ġ* Ġdisabled . ĠThis ĠUI Ġis Ġnot Ġcustom izable . Ċ Ġ* Ċ Ġ* ĠExample : Ċ Ġ* Ċ Ġ* Ġ``` Ċ Ġ* Ġ@ Composable Ċ Ġ* Ġfun ĠN ear by Rest aurants () Ġ{ Ċ Ġ* ĠĠĠĠ ĠLocation Fetcher ( Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġrequest Config Ġ= Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġinterval Ġ= Ġ 1 5 . seconds . in Whole Milliseconds Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġfast est Interval Ġ= Ġ 1 5 . seconds . in Whole Milliseconds Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġpriority Ġ= ĠLocation Request . PRIORITY _ HIGH _ AC CUR ACY Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġ}, Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġr ationale Ġ= Ġ" We Ġneed Ġyour Ġlocation Ġfor Ġfinding Ġnearby Ġrest aurants ." Ċ Ġ* ĠĠĠĠ Ġ) Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġval Ġ( location Result , Ġsetting Enabled , Ġpermissions Granted ) Ġ= ĠLocal Location Fetcher . current Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġwhen Ġ( location Result ) Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> ĠMissing Location () Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠN ear by Rest aurants ( location Result ) Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠĠ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ*/ Ċ @ Composable Ċ public Ġfun ĠLocation Fetcher ( ĊĠĠĠ Ġrequest Config : ĠLocation Request . () Ġ-> ĠUnit Ġ= Ġ{}, ĊĠĠĠ Ġr ationale : ĠString , ĊĠĠĠ Ġcontent : Ġ@ Composable Ġ() Ġ-> ĠUnit Ċ ) Ġ{ ĊĠĠĠ Ġval Ġr ationale Ui : ĠR ationale Ui Ġ= Ġremember ( ration ale ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ{ Ġon R ationale Dis missed Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR ationale ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġr ationale , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon R ationale Dis missed Ġ= Ġon R ationale Dis missed , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ ĠLocation Fetcher ( ĊĠĠĠĠĠĠĠ Ġrequest Config Ġ= Ġrequest Config , ĊĠĠĠĠĠĠĠ Ġr ationale Ui Ġ= Ġr ationale Ui , ĊĠĠĠĠĠĠĠ Ġcontent Ġ= Ġcontent , ĊĠĠĠ Ġ) Ċ } Ċ Ċ /** Ċ Ġ* ĠObtain Ġperiodic Ġlocation Ġupdates Ġfrom Ġthe Ġdevice . ĠThe Ġ[ Location Result ] Ġis Ġdelivered Ġto Ġall Ċ Ġ* Ġchildren Ġcomp osable Ġby Ġa Ġ[ Composition Local ]: Ġ[ Local Location Fetcher . current ]. Ċ Ġ* Ċ Ġ* Ġ[ Location Request ] Ġconfigurations Ġcan Ġbe Ġset Ġby Ġ[ request Config ]. Ċ Ġ* Ċ Ġ* ĠIf Ġthe Ġlocation Ġpermissions Ġare Ġnot Ġgranted Ġby Ġthe Ġuser , Ġthis Ġ[ Composable ] Ġwill Ġrequest Ġthem Ċ Ġ* Ġto Ġthe Ġuser . ĠIf Ġthe ĠAndroid Ġframework Ġtells Ġthat Ġa Ġr ationale Ġfor Ġrequesting Ġthe Ġpermissions Ġmust Ċ Ġ* Ġbe Ġpresented , Ġa Ġ[ custom Ġr ationale ĠUI ][ ration ale Ui ] Ġwill Ġbe Ġused . Ġ** The Ġr ationale ĠUI Ġmust Ġcall Ċ Ġ* Ġthe Ġ` on R ationale Dis missed ` Ġcallback Ġonce Ġuser Ġdis mis ses Ġthe ĠUI **. ĠThe Ġcallback Ġwill Ġbe Ġthe Ċ Ġ* Ġtrigger Ġfor Ġactually Ġasking Ġfor Ġthe Ġlocation Ġpermissions . Ċ Ġ* Ċ Ġ* ĠIf Ġyou Ġprefer Ġto Ġuse Ġa Ġpredefined Ġr ationale ĠUI Ġinstead , Ġsee Ġthe Ġoverload Ġthat Ġtakes Ġin Ġa Ċ Ġ* Ġr ationale ĠString Ġinstead Ġof Ġa Ġr ationale ĠUI . Ċ Ġ* Ċ Ġ* ĠOnce Ġlocation Ġpermissions Ġare Ġgranted Ġby Ġthe Ġuser , Ġthis Ġ[ Composable ] Ġwill Ġcheck Ġwhether Ġlocation Ċ Ġ* Ġsettings Ġare Ġenabled Ġin Ġthe ĠAndroid Ġsettings , Ġasking Ġthe Ġuser Ġto Ġenable Ġthem Ġin Ġcase Ġthey 're Ċ Ġ* Ġdisabled . ĠThis ĠUI Ġis Ġnot Ġcustom izable . Ċ Ġ* Ċ Ġ* ĠExample : Ċ Ġ* Ċ Ġ* Ġ``` Ċ Ġ* Ġ@ Composable Ċ Ġ* Ġfun ĠN ear by Rest aurants () Ġ{ Ċ Ġ* ĠĠĠĠ ĠLocation Fetcher ( Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġrequest Config Ġ= Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġinterval Ġ= Ġ 1 5 . seconds . in Whole Milliseconds Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġfast est Interval Ġ= Ġ 1 5 . seconds . in Whole Milliseconds Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġpriority Ġ= ĠLocation Request . PRIORITY _ HIGH _ AC CUR ACY Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġ}, Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġr ationale Ui Ġ= Ġ{ Ġon R ationale Dis missed Ġ-> Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocation Permission R ationale ( Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Dismiss Ġ= Ġon R ationale Dis missed Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġ}, Ċ Ġ* ĠĠĠĠ Ġ) Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġval Ġ( location Result , Ġsetting Enabled , Ġpermissions Granted ) Ġ= ĠLocal Location Fetcher . current Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġwhen Ġ( location Result ) Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> ĠMissing Location () Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠN ear by Rest aurants ( location Result ) Ċ Ġ* ĠĠĠĠĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠĠ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ*/ Ċ @ Composable Ċ public Ġfun ĠLocation Fetcher ( ĊĠĠĠ Ġrequest Config : ĠLocation Request . () Ġ-> ĠUnit Ġ= Ġ{}, ĊĠĠĠ Ġr ationale Ui : ĠR ationale Ui , ĊĠĠĠ Ġcontent : Ġ@ Composable Ġ() Ġ-> ĠUnit Ċ ) Ġ{ ĊĠĠĠ Ġval Ġcontext Ġ= ĠLocal Context . current ĊĠĠĠ Ġval Ġstate Ġ= Ġremember Ġ{ ĠLocation Context ( context . has Location Permissions ()) Ġ} ĊĠĠĠ ĠPermission Request ( ĊĠĠĠĠĠĠĠ Ġpermissions Granted Ġ= Ġstate . permissions Granted , ĊĠĠĠĠĠĠĠ Ġset Permissions Granted Ġ= Ġstate :: update Permissions Granted , ĊĠĠĠĠĠĠĠ Ġr ationale Dis missed Ġ= Ġstate . ration ale Dis missed ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġr ationale Ui ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon R ationale Dis missed Ġ= Ġstate :: ration ale Dis missed ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( state . permissions Granted ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlocation Request Ġ= Ġremember Location Request ( request Config ) ĊĠĠĠĠĠĠĠ ĠSettings Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Request Ġ= Ġlocation Request , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Setting Enabled Ġ= Ġstate :: update Setting Enabled ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠLocation Provider ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Request Ġ= Ġlocation Request , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Location Ġ= Ġstate :: update Location ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġlocation State Ġby Ġremember Ġ{ ĊĠĠĠĠĠĠĠ Ġderived State Of Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLocation State ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Result Ġ= Ġstate . location ?. location Result , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetting Enabled Ġ= Ġstate . setting Enabled , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpermissions Granted Ġ= Ġstate . permissions Granted ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ ĠComp osition Local Provider ( ĊĠĠĠĠĠĠĠ ĠLocal Location Fetcher Ġprovides Ġlocation State , ĊĠĠĠĠĠĠĠ Ġcontent Ġ= Ġcontent ĊĠĠĠ Ġ) Ċ } Ċ Ċ public Ġobject ĠLocal Location Fetcher Ġ{ ĊĠĠĠ Ġprivate Ġval ĠLocal Location Fetcher Ġ= ĊĠĠĠĠĠĠĠ Ġcomposition Local Of < Location State > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Can Ġonly Ġbe Ġcalled Ġthrough ĠLocation Fetcher ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġval Ġcurrent : ĠLocation State ĊĠĠĠĠĠĠĠ Ġ@ Composable ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠLocal Location Fetcher . current ĊĊĠĠĠ Ġinternal Ġin fix Ġfun Ġprovides ( ĊĠĠĠĠĠĠĠ Ġlocation : ĠLocation State ĊĠĠĠ Ġ): ĠProvide d Value < Location State > Ġ= ĊĠĠĠĠĠĠĠ ĠLocal Location Fetcher Ġprovides Ġlocation Ċ } Ċ Ċ public Ġtype alias ĠR ationale Ui Ġ= Ġ@ Composable Ġ( on R ationale Dis missed : Ġ() Ġ-> ĠUnit ) Ġ-> ĠUnit Ċ Ċ // Ġ---- ĠImplementation Ġ---- Ċ Ċ @ Composable Ċ private Ġfun ĠR ationale ( ĊĠĠĠ Ġtext : ĠString , ĊĠĠĠ Ġon R ationale Dis missed : Ġ() Ġ-> ĠUnit Ċ ) Ġ{ ĊĠĠĠ ĠAlertDialog ( ĊĠĠĠĠĠĠĠ Ġtext Ġ= Ġ{ ĠText ( text Ġ= Ġtext ) Ġ}, ĊĠĠĠĠĠĠĠ Ġon Dismiss Request Ġ= Ġon R ationale Dis missed , ĊĠĠĠĠĠĠĠ Ġconfirm Button Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠButton ( onClick Ġ= Ġon R ationale Dis missed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText ( text Ġ= Ġstring Resource ( id Ġ= Ġandroid . R . string . ok )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ) Ċ } Ċ Ċ @ Composable Ċ private Ġfun Ġremember Location Request ( request Config : ĠLocation Request . () Ġ-> ĠUnit ) Ġ= ĊĠĠĠ Ġremember ( request Config ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLocation Request Wrapper ( Location Request . create (). apply ( request Config )) ĊĠĠĠ Ġ} Ċ Ċ @ Stable Ċ private Ġclass ĠLocation Context ( permissions Granted : ĠBoolean ) Ġ{ ĊĠĠĠ Ġvar Ġlocation Ġby Ġmutable State Of < Location Result Wrapper ? >( null ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġpermissions Granted Ġby Ġmutable State Of ( permissions Granted ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġsetting Enabled Ġby Ġmutable State Of < Boolean ? >( null ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġr ationale Dis missed Ġby Ġmutable State Of ( false ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġfun Ġupdate Permissions Granted ( gr anted : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġr ationale Dis missed Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġpermissions Granted Ġ= Ġgranted ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupdate Setting Enabled ( enabled : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsetting Enabled Ġ= Ġenabled ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupdate Location ( location : ĠLocation Result Wrapper ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . location Ġ= Ġlocation ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġr ationale Dis missed () Ġ{ ĊĠĠĠĠĠĠĠ Ġr ationale Dis missed Ġ= Ġtrue ĊĠĠĠ Ġ} Ċ } Ċ