package Ġcom . example . weather _ app . views Ċ Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . content . Intent Ċ import Ġandroid . location . Geo coder Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . widget . Toast Ċ import Ġandroidx . activity . view Models Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . core . content . Context Compat Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġandroidx . lifecycle . lifecycle Scope Ċ import Ġandroidx . recyclerview . widget . Linear LayoutManager Ċ import Ġcom . example . weather _ app . R Ċ import Ġcom . example . weather _ app . adapters . Hour ly Forecast Adapter Ċ import Ġcom . example . weather _ app . adapters . Vertical Weather Data Adapter Ċ import Ġcom . example . weather _ app . databinding . Activity Weather Forecast Binding Ċ import Ġcom . example . weather _ app . utils . Ui Utils Ċ import Ġcom . example . weather _ app . view models . Weather Forecast Activity ViewModel Ċ import Ġcom . example . weather _ app . web services . entities . current weather data . Current Weather Data Response Ċ import Ġcom . example . weather _ app . web services . entities . weather forecast data . Weather Forecast Data Response Ċ import Ġcom . google . android . gms . location . Location Services Ċ import Ġcom . vm ad al in . eas yper missions . Easy Permissions Ċ import Ġdagger . h ilt . android . Android EntryPoint Ċ import Ġkotlinx . coroutines . launch Ċ import Ġjava . util .* Ċ Ċ private Ġconst Ġval ĠPER MISSION _ LOCATION _ REQUEST _ CODE Ġ= Ġ 1 0 Ċ @ Android EntryPoint Ċ class ĠWeather Forecast Activity Ġ: ĠAppCompatActivity (), ĠEasy Permissions . Permission Callbacks Ġ{ ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġbinding : ĠActivity Weather Forecast Binding ĊĠĠĠ Ġprivate Ġval ĠviewModel : ĠWeather Forecast Activity ViewModel Ġby Ġview Models () ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( ĊĠĠĠĠĠĠĠ ĠsavedInstanceState : ĠBundle ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ Ġbinding Ġ= ĠActivity Weather Forecast Binding . inflate ( layout Inflater ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( binding . root ) ĊĊĠĠĠĠĠĠĠ Ġcheck Permissions () ĊĠĠĠĠĠĠĠ Ġget Device Location () ĊĠĠĠĠĠĠĠ ĠsetUp Recycler Views () ĊĠĠĠĠĠĠĠ ĠsetUp Click Listeners () ĊĊĠĠĠĠĠĠĠ Ġval Ġcurrent Weather Data Observer Ġ= ĠObserver < Current Weather Data Response > Ġ{ ĠnewData Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Background () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Text Views ( new Data ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠviewModel . current Weather Data . observe ( this , current Weather Data Observer ) ĊĠĠĠĠĠĠĠ Ġval Ġweather Forecast Data Observer Ġ= ĠObserver < Weather Forecast Data Response > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Recycler Views () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠviewModel . weather Forecast Data . observe ( this , weather Forecast Data Observer ) ĊĠĠĠĠĠĠĠ Ġval Ġerror Status Observer Ġ= ĠObserver < Boolean > Ġ{ Ġstatus Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( status ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . error Status . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Insert Local ity Dialog ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context . getString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . did nt _ found _ city ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠviewModel . error Status . observe ( this , error Status Observer ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Request Permissions Result ( ĊĠĠĠĠĠĠĠ Ġrequest Code : ĠInt , ĊĠĠĠĠĠĠĠ Ġpermissions : ĠArray < out ĠString >, ĊĠĠĠĠĠĠĠ Ġgrant Results : ĠInt Array ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Request Permissions Result ( request Code , Ġpermissions , Ġgrant Results ) ĊĠĠĠĠĠĠĠ ĠEasy Permissions . on Request Permissions Result ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Code , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpermissions , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrant Results , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Permissions Denied ( ĊĠĠĠĠĠĠĠ Ġrequest Code : ĠInt , ĊĠĠĠĠĠĠĠ Ġperms : ĠList < String > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġshow Insert Local ity Dialog ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context . getString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . no _ permission _ dialog _ message ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Permissions Granted ( ĊĠĠĠĠĠĠĠ Ġrequest Code : ĠInt ĊĠĠĠĠĠĠĠ Ġ, Ġperms : ĠList < String > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ ĠToast . makeText ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Location Ġpermission Ġgranted .", ĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . LENGTH _ SHORT ĊĠĠĠĠĠĠĠ Ġ). show () ĊĠĠĠĠĠĠĠ Ġget Device Location () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Permissions () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! has Location Permission ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Location Permission () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Location Permission () Ġ= ĠEasy Permissions . has Permissions ( ĊĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠ Ġandroid . Manifest . permission . ACCESS _ F INE _ LOCATION ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun Ġrequest Location Permission () Ġ{ ĊĠĠĠĠĠĠĠ ĠEasy Permissions . request Permissions ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" This Ġapplication Ġworks Ġbest Ġwith Ġlocation Ġpermission ", ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPER MISSION _ LOCATION _ REQUEST _ CODE , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid . Manifest . permission . ACCESS _ F INE _ LOCATION ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress Lint (" Missing Permission ") ĊĠĠĠ Ġprivate Ġfun Ġget Device Location () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġf used Location Provider Client Ġ= ĠLocation Services . getF used Location Provider Client ( this ) ĊĠĠĠĠĠĠĠ Ġif Ġ( has Location Permission ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġf used Location Provider Client . last Location . add On Success Listener Ġ{ Ġlocation Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( location Ġ== Ġnull ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Insert Local ity Dialog ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context . getString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . insert _ location _ dialog _ description ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlat Ġ= Ġlocation . latitude ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlon Ġ= Ġlocation . longitude ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlocal ity Ġ= ĠGeo coder ( this ). get From Location ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlat , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlon , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). first (). locality ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( locality Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Insert Local ity Dialog ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context . getString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . insert _ location _ dialog _ description ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . update Device Location ( locality ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Insert Local ity Dialog ( ĊĠĠĠĠĠĠĠ Ġdialog Message : ĠString ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdialog Ġ= ĠInsert Location Dialog ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdialog Message , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbtn Submit ClickListener Ġ= Ġ{ Ġlocal ity Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . update Device Location ( locality ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġdialog . show ( support FragmentManager ," insert Location Dialog ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠsetUp Click Listeners () Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding . btn City Selection . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( this , City Selection Activity :: class . java ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartActivity ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbinding . btn Refresh . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . download Weather Data () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠsetUp Recycler Views (){ ĊĠĠĠĠĠĠĠ Ġbinding . rv Hour ly Forecast . layout Manager Ġ= ĠLinearLayoutManager ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLinearLayoutManager . HORIZONTAL , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġbinding . rv Vertical Weather Data . layout Manager Ġ= ĠLinearLayoutManager ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLinearLayoutManager . VERTICAL , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Background (){ ĊĠĠĠĠĠĠĠ Ġval Ġweather Tag Ġ= ĠviewModel . current Weather Data . value !!. weather [ 0 ]. icon ĊĠĠĠĠĠĠĠ Ġval Ġheader Color Int Ġ= ĠUi Utils . getHeader Color ( weather Tag ) ĊĠĠĠĠĠĠĠ Ġwindow . status Bar Color Ġ= ĠContext Compat . getColor ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUi Utils . getStatus Bar Color ( weather Tag ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġbinding . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroot . setBackground Resource ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUi Utils . get Weather Forecast Background ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġweather Tag ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdivider Top Hour ly Forecast . setBackground Resource ( header Color Int ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdivider Bottom Hour ly Forecast . setBackground Resource ( header Color Int ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdivider . setBackground Resource ( header Color Int ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Text Views ( ĊĠĠĠĠĠĠĠ Ġdata : ĠCurrent Weather Data Response ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv City . text Size Ġ= Ġ 4 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv City . text Ġ= Ġdata . name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv Weather Description . text Ġ= Ġdata . weather [ 0 ]. description . replace First Char Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . is LowerCase ()) Ġit . title case ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocale . getDefault () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġelse Ġit . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv Temp . text Ġ= ĠgetString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . temp , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . main . temp . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv H . text Ġ= ĠgetString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . main _ H _ temp , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . main . temp _ max . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv L . text Ġ= ĠgetString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . main _ L _ temp , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . main . temp _ min . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv Api Call Time . setTextColor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext Compat . getColor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUi Utils . getHeader Color ( viewModel . current Weather Data . value !!. weather [ 0 ]. icon ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtv Api Call Time . text Ġ= ĠviewModel . get Api Call Time () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġ Ġupdate Recycler Views () Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding . rv Hour ly Forecast . adapter Ġ= ĠHour ly Forecast Adapter ( viewModel . get Hour ly Forecast List ()) ĊĠĠĠĠĠĠĠ Ġbinding . rv Vertical Weather Data . adapter Ġ= ĠVertical Weather Data Adapter ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . current Weather Data . value !!. weather [ 0 ]. icon , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . get Vertical Weather DataList () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ } Ċ