/* Ċ Ġ* ĠCopyright Ġ 2 0 1 7 ĠGoogle ĠInc . ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . example . android . u amp Ċ Ċ import Ġandroid . Manifest Ċ import Ġandroid . Manifest . permission Ċ import Ġandroid . content . pm . PackageManager Ċ import Ġandroid . media . Audio Manager Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . view . View Ċ import Ġandroid . widget . Toast Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . core . app . Activity Compat Ċ import Ġandroidx . core . content . Context Compat Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġandroidx . lifecycle . ViewModel Providers Ċ import Ġcom . example . android . u amp . fragments . Media Item Fragment Ċ import Ġcom . example . android . u amp . media . Music Service Ċ import Ġcom . example . android . u amp . utils . Event Ċ import Ġcom . example . android . u amp . utils . Injector Utils Ċ import Ġcom . example . android . u amp . utils . show Snackbar Ċ import Ġcom . example . android . u amp . view models . MainActivity ViewModel Ċ import Ġcom . google . android . material . sn ackbar . Snackbar ĊĊ Ċ class ĠMainActivity Ġ: ĠAppCompatActivity () Ġ{ ĊĠĠĠ Ġprivate Ġlateinit Ġvar ĠviewModel : ĠMainActivity ViewModel ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġlayout : ĠView ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( R . layout . activity _ main ) ĊĠĠĠĠĠĠĠ Ġlayout Ġ= ĠfindViewById ( R . id . fragment Container ) ĊĊĊĠĠĠĠĠĠĠ Ġ// ĠSince Ġthis Ġapp Ġhas Ġa Ġmusic Ġplayer , Ġthe Ġvolume Ġcontrols Ġshould Ġadjust Ġthe Ġmusic Ġvolume ĊĠĠĠĠĠĠĠ Ġ// Ġwhile Ġin Ġthe Ġapp . ĊĠĠĠĠĠĠĠ Ġvolume Control Stream Ġ= ĠAudio Manager . STREAM _ M US IC ĊĊĠĠĠĠĠĠĠ ĠviewModel Ġ= ĠViewModel Providers ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. of ( this , ĠInject or Utils . provide MainActivity ViewModel ( this )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. get ( MainActivity ViewModel :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( Context Compat . check Self Permission ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpermission . ACCESS _ CO AR SE _ LOCATION ) Ġ!= ĠPackage Manager . PERMISSION _ GRAN TED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Location Permission () ĊĠĠĠĠĠĠĠ Ġ//} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠPermission Ġhas Ġalready Ġbeen Ġgranted ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠOb serve Ġ[ MainActivity ViewModel . navigate To Fragment ] Ġfor Ġ[ Event ] s Ġthat Ġrequest Ġa ĊĠĠĠĠĠĠĠĠ Ġ* Ġfragment Ġswap . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ ĠviewModel . navigate To Fragment . observe ( this , ĠObserver Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit ?. getContent IfNot Handled ()?. let Ġ{ Ġfragment Request Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransaction Ġ= Ġsupport FragmentManager . beginTransaction () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . replace ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . fragment Container , Ġfragment Request . fragment , Ġfragment Request . tag ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( fragment Request . back Stack ) Ġtransaction . addTo Back Stack ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . commit () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠOb serve Ġchanges Ġto Ġthe Ġ[ MainActivity ViewModel . root Media Id ]. ĠWhen Ġthe Ġapp Ġstarts , ĊĠĠĠĠĠĠĠĠ Ġ* Ġand Ġthe ĠUI Ġconnects Ġto Ġ[ Music Service ], Ġthis Ġwill Ġbe Ġupdated Ġand Ġthe Ġapp Ġwill Ġshow ĊĠĠĠĠĠĠĠĠ Ġ* Ġthe Ġinitial Ġlist Ġof Ġmedia Ġitems . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ ĠviewModel . root Media Id . observe ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠObserver Ġ{ Ġroot Media Id Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( root Media Id Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnavigate To Media Item ( root Media Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠOb serve Ġ[ MainActivity ViewModel . navigate To Media Item ] Ġfor Ġ[ Event ] s Ġindicating ĊĠĠĠĠĠĠĠĠ Ġ* Ġthe Ġuser Ġhas Ġrequested Ġto Ġbrowse Ġto Ġa Ġdifferent Ġ[ Media Item Data ]. ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ ĠviewModel . navigate To Media Item . observe ( this , ĠObserver Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit ?. getContent IfNot Handled ()?. let Ġ{ Ġmedia Id Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnavigate To Media Item ( media Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnavigate To Media Item ( media Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġfragment : ĠMedia Item Fragment ? Ġ= Ġget Browse Fragment ( media Id ) ĊĠĠĠĠĠĠĠ Ġif Ġ( fragment Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfragment Ġ= ĠMedia Item Fragment . newInstance ( media Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthis Ġis Ġnot Ġthe Ġtop Ġlevel Ġmedia Ġ( root ), Ġwe Ġadd Ġit Ġto Ġthe Ġfragment ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġback Ġstack , Ġso Ġthat Ġaction bar Ġtoggle Ġand ĠBack Ġwill Ġwork Ġappropriately : ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . show Fragment ( fragment , Ġ! is Root Id ( media Id ), Ġmedia Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Root Id ( media Id : ĠString ) Ġ= Ġmedia Id Ġ== ĠviewModel . root Media Id . value ĊĊĠĠĠ Ġprivate Ġfun Ġget Browse Fragment ( media Id : ĠString ): ĠMedia Item Fragment ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsupport FragmentManager . find Fragment By Tag ( media Id ) Ġas ĠMedia Item Fragment ? ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrequest Location Permission () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠShould Ġwe Ġshow Ġan Ġexplanation ? ĊĠĠĠĠĠĠĠ Ġif Ġ( Activity Compat . should Show Request Permission R ationale ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠManifest . permission . ACCESS _ CO AR SE _ LOCATION )) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlayout . show Snackbar ( R . string . location _ course _ access _ required , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSn ackbar . LENGTH _ IN DEFIN ITE , ĠR . string . ok ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠActivity Compat . request Permissions ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( Manifest . permission . ACCESS _ CO AR SE _ LOCATION ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠREQUEST _ ACCESS _ CO AR SE _ LOCATION _ CODE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNo Ġexplanation Ġneeded , Ġwe Ġcan Ġrequest Ġthe Ġpermission . ĊĠĠĠĠĠĠĠĠĠĠĠ ĠActivity Compat . request Permissions ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( Manifest . permission . ACCESS _ CO AR SE _ LOCATION ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠREQUEST _ ACCESS _ CO AR SE _ LOCATION _ CODE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠREQUEST _ ACCESS _ CO AR SE _ LOCATION _ CODE Ġis Ġan Ġapp - defined Ġinit Ġconstant ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġcallback Ġmethod Ġ( below ) Ġgets Ġthe Ġresult Ġof Ġthe Ġrequest . ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHandle Ġthe Ġpermissions Ġrequest Ġresponse ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon Request Permissions Result ( request Code : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpermissions : ĠArray < String >, Ġgrant Results : ĠInt Array ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( request Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠREQUEST _ ACCESS _ CO AR SE _ LOCATION _ CODE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġrequest Ġis Ġcancelled , Ġthe Ġresult Ġarrays Ġare Ġempty . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(( grant Results . isNotEmpty () Ġ&& Ġgrant Results [ 0 ] Ġ== ĠPackage Manager . PERMISSION _ GRAN TED )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( application Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . permission _ gr anted , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . LENGTH _ LONG ). show () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġpermission Ġwas Ġgranted , Ġy ay ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( application Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . permission _ not _ gr anted , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . LENGTH _ LONG ). show () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// TODO : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġpermission Ġdenied , Ġb oo ! ĠDisable Ġthe Ġfunctionality Ġthat Ġdepends Ġon Ġthis Ġpermission . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdd Ġother Ġ' when ' Ġlines Ġto Ġcheck Ġfor Ġother ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġpermissions Ġthis Ġapp Ġmight Ġrequest . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIgnore Ġall Ġother Ġrequests . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġconst Ġval ĠREQUEST _ ACCESS _ CO AR SE _ LOCATION _ CODE Ġ= Ġ 2