/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠB am mell ab Ġ/ ĠJames ĠAnd reas Ċ Ġ* Ġ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 Ċ Ġ*/ Ċ Ċ @ file : Suppress (" UNUSED _ VARIABLE ", Ġ" unused ", Ġ" UNUSED _ PARAMETER ") Ċ Ċ package Ġcom . bam mell ab . gamepad test Ċ Ċ import Ġandroid . bluetooth . Bluetooth Adapter Ċ import Ġandroid . content . Intent Filter Ċ import Ġandroid . content . SharedPreferences Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . util . Log Ċ import Ġandroid . view . Input Device Ċ import Ġandroid . view . KeyEvent Ċ import Ġandroid . view . Menu Ċ import Ġandroid . view . Motion Event Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . lifecycle . Lifecycle Observer Ċ import Ġandroidx . navigation . Nav Destination Ċ import Ġandroidx . navigation . find Nav Controller Ċ import Ġandroidx . navigation . ui . AppBar Configuration Ċ import Ġandroidx . navigation . ui . setup ActionBar With Nav Controller Ċ import Ġandroidx . navigation . ui . setup With Nav Controller Ċ import Ġandroidx . preference . Preference Manager Ċ import Ġcom . bam mell ab . gamepad test . gamepad . Gamepad Services Ċ import Ġcom . bam mell ab . gamepad test . ui . settings . Settings Fragment . Companion . bash The Theme Ċ import Ġcom . google . android . material . bottomnavigation . Bottom Navigation View ĊĊ Ċ class ĠMainActivity Ġ: ĊĠĠĠ ĠAppCompatActivity (), ĠLifecycle Observer , ĠSharedPreferences . On Shared Preference ChangeListener Ġ Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġnav View : ĠBottom Navigation View ĊĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( R . layout . activity _ main ) ĊĠĠĠĠĠĠĠ Ġnav View Ġ= ĠfindViewById ( R . id . nav _ view ) ĊĊĠĠĠĠĠĠĠ Ġval Ġnav Controller Ġ= Ġfind Nav Controller ( R . id . nav _ host _ fragment ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠPass ing Ġeach Ġmenu ĠID Ġas Ġa Ġset Ġof ĠI ds Ġbecause Ġeach ĊĠĠĠĠĠĠĠ Ġ// Ġmenu Ġshould Ġbe Ġconsidered Ġas Ġtop Ġlevel Ġdest inations . ĊĠĠĠĠĠĠĠ Ġval Ġapp Bar Configuration Ġ= ĠApp Bar Configuration ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . navigation _ scan , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . navigation _ gamepad , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . navigation _ log , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . navigation _ settings ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġsetup ActionBar With Nav Controller ( nav Controller , Ġapp Bar Configuration ) ĊĠĠĠĠĠĠĠ Ġnav View . setup With Nav Controller ( nav Controller ) ĊĊĠĠĠĠĠĠĠ Ġnav Controller . add On Destination Changed Listener Ġ{ Ġ_, Ġdestination : ĠNav Destination , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtool Bar Ġ= Ġsupport ActionBar Ġ?: Ġreturn @ add On Destination Changed Listener ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( destination . id ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . navigation _ gamepad Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtool Bar . set Display Show Title Enabled ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtool Bar . title Ġ= ĠgetString ( R . string . app _ name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . navigation _ scan Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtool Bar . set Display Show Title Enabled ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . navigation _ log Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtool Bar . set Display Show Title Enabled ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtool Bar . set Display Show Title Enabled ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠListen Ġfor Ġpreference Ġchanges ĊĠĠĠĠĠĠĠ Ġval Ġprefs : ĠSharedPreferences Ġ= ĠPreference Manager . getDefault SharedPreferences ( this ) ĊĠĠĠĠĠĠĠ Ġprefs . register On Shared Preference ChangeListener ( this ) ĊĠĠĠĠĠĠĠ Ġbash The Theme ( prefs , Ġresources ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠ Ġ* Ġthis Ġis Ġadded Ġas Ġsuggested Ġhere : ĊĠĠĠĠĠĠĠĠ Ġ* Ġhttps :// stackoverflow . com / a / 5 7 7 7 2 2 8 7 ĊĠĠĠĠĠĠĠĠ Ġ* Ġto Ġtry Ġto Ġtrack Ġdown Ġstrict Ġmode ĠGoogle ĠPlay Ġreporting . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ/* try Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build Config . BUILD _ TYPE . content Equals (" debug ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStrict Mode . set Thread Policy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStrict Mode . Thread Policy . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. detect All () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. penalty Log () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( android . os . Build . VERSION . SDK _ INT Ġ>= Ġandroid . os . Build . VERSION _ CODES . P ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStrict Mode . set Vm Policy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠVm Policy . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. detect Non Sdk Api Usage () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. penalty Log () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" MainActivity ", Ġ" Fail Ġon ĠStrict Mode Ġsetup ") ĊĠĠĠĠĠĠĠ Ġ}*/ ĊĊĠĠĠĠĠĠĠ Ġval Ġfilter Ġ= ĠIntent Filter ( Bluetooth Adapter . ACTION _ STATE _ CHANGED ) ĊĠĠĠĠĠĠĠ Ġregister Receiver ( Gamepad Services . broadcast Receiver , Ġfilter ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġhandle Ġthe Ġkey Ġevents Ġ- ĊĠĠĠĠ Ġ* ĠĠĠ ĠDon 't Ġpass Ġthe Ġkey Ġevent Ġto Ġthe Ġframework ĊĠĠĠĠ Ġ* ĠĠĠ Ġor Ġelse Ġthe ĠBottom ĠNavigation Ġgets Ġactive ĊĠĠĠĠ Ġ* ĠĠĠ Ġwhen Ġit Ġshould Ġnot . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon KeyDown ( keyCode : ĠInt , Ġevent : ĠKeyEvent ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġhandle System Keys ( keyCode , Ġevent ) ĊĠĠĠĠĠĠĠ ĠGame pad Services . gamepad Button Service . forward Button Down ( keyCode , Ġevent ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon KeyUp ( keyCode : ĠInt , Ġevent : ĠKeyEvent ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ ĠGame pad Services . gamepad Button Service . forward Button Up ( keyCode , Ġevent ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġhandle Ġthe Ġevents Ġfrom Ġthe : ĊĠĠĠĠ Ġ* Ġ Ġ-> Ġjo yst icks ĊĠĠĠĠ Ġ* Ġ Ġ-> ĠD pad Ġ( they Ġare Ġmotion Ġevents , ĠI Ġdon 't Ġsee Ġkey ĠEvents Ġfrom Ġthe ĠTR UST ĠM XP Ġgame pad ) ĊĠĠĠĠ Ġ* Ġ Ġ-> ĠT riggers ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ ĠThe Ġhistorical Ġposition Ġevents Ġdon 't Ġseem Ġto Ġhave Ġmuch Ġvalue . ĊĠĠĠĠ Ġ* Ġ ĠMaybe Ġthey Ġare Ġmore Ġim mp ort ant Ġfor Ġa Ġst yl us Ġand Ġgraph ix Ġpad Ġor Ġsome th img . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon Generic Motion Event ( event : ĠMotion Event ): ĠBoolean Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġjo yst Ġ= ĠGame pad Services . gamepad Joystick Service ĊĊĠĠĠĠĠĠĠ Ġ// ĠCheck Ġthat Ġthe Ġevent Ġcame Ġfrom Ġa Ġgame Ġcontroller ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( event . source Ġand ĠInput Device . SOURCE _ JOY STICK Ġ== ĠInput Device . SOURCE _ JOY STICK ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġevent . action Ġ== ĠMotion Event . ACTION _ MOVE ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ Ġ Ġ// ĠSee ing Ġan Ġexception Ġin Ġthis Ġcall Ġon Ġsome Ġdevices . Ġ ĠNot Ġclear Ġwhat Ġthe Ġproblem Ġis . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjo yst . process Joystick Input ( this , Ġevent ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" on Generic Motion Event ", Ġ" Exception Ġcaught ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Generic Motion Event ( event ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Menu Opened ( feature Id : ĠInt , Ġmenu : ĠMenu ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . i (" GAME PAD ", Ġ" on MENU ĠOPEN ED Ġ***************** ** ") ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . on Menu Opened ( feature Id , Ġmenu ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExam ine Ġkey Ġevents Ġfor Ġsystem Ġfunctions . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠTODO : Ġvector Ġback Ġkey Ġto Ġone Ġfragment Ġfirst , Ġthen Ġexit . Ġ ĠRight Ġnow Ġjust Ġexit ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġhandle System Keys ( keyCode : ĠInt , Ġevent : ĠKeyEvent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( event Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġsource Ġ= Ġevent . source ĊĠĠĠĠĠĠĠ Ġval Ġflags Ġ= Ġevent . flags ĊĠĠĠĠĠĠĠ Ġval Ġsys Ġ= ĠKeyEvent . FLAG _ FROM _ SYSTEM ĊĊĠĠĠĠĠĠĠ Ġif Ġ( source Ġ== Ġ 2 5 7 ) Ġ{ Ġ Ġ// Ġnot Ġfrom Ġany Ġgame Ġcontroller ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(( flags Ġand Ġsys ) Ġ== Ġsys ) Ġ{ Ġ// Ġis Ġa Ġsystem Ġkey code ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( keyCode Ġ== ĠKeyEvent . KEYCODE _ BACK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Destroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġshared Preferences Ġ= ĠPreference Manager . getDefault SharedPreferences ( this ) ĊĠĠĠĠĠĠĠ Ġshared Preferences . unregister On Shared Preference ChangeListener ( this ) ĊĠĠĠĠĠĠĠ Ġsuper . on Destroy () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Shared Preference Changed ( shared Preferences : ĠSharedPreferences ?, Ġkey : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog Motion Events Key Ġ= ĠgetString ( R . string . settings _ log _ motion _ key ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( key ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Motion Events Key Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpref bool Ġ= Ġshared Preferences ?. getBoolean ( log Motion Events Key , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pref bool Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGame pad Services . gamepad Logger Service . flag To Log Motion Events ( pref bool ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } ĊĊ