package Ġcom . x ific s . usb . otg Ċ Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . content . Broadcast Receiver Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . Intent Filter Ċ import Ġandroid . hardware . usb .* Ċ import Ġandroid . os . Handler Ċ import Ġandroid . util . Log Ċ Ċ /** Ċ * ĠCreated Ġby ĠX ific s Ġon Ġ 2 0 1 8 / 0 3 / 0 4 . Ċ */ Ċ open Ġclass ĠU sb HID Reader ( context : ĠContext ) Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPER MISSION Ġ= Ġ" com . x ific s . usb . PERMISSION " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠREAD _ INTERVAL _ M ILL IS Ġ= Ġ 5 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Usb HID Reader " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġm Permission Receiver Ġ= Ġobject Ġ: ĠBroadcast Receiver () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Receive ( context : ĠContext , Ġintent : ĠIntent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( intent . action Ġ== ĠPER MISSION ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( intent . getBoolean Extra ( Usb Manager . EXTRA _ PERMISSION _ GRAN TED , Ġfalse )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . get Parcelable Extra < Usb Device >( Usb Manager . EXTRA _ DEVICE )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop Thread () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Device Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ĠRe consider ĠU sb Barcode Callback ĠFormat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Callback ?. on Device Connected ( it . product Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Thread () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠmContext . unregister Receiver ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Callback ?. onError (" permission Ġdenied ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġm Attach And Detach Receiver Ġ= Ġobject Ġ: ĠBroadcast Receiver () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Receive ( context : ĠContext , Ġintent : ĠIntent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( intent . action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠU sb Manager . ACTION _ USB _ DEVICE _ ATTACH ED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . get Parcelable Extra < Usb Device >( Usb Manager . EXTRA _ DEVICE )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġin Ġcase Ġof Ġconnect Ġa Ġusb Ġdevice Ġafter Ġthis Ġreceiver Ġregistered ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Manager . request Permission ( m Device , ĠPending Intent . get Broadcast ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠmContext , Ġ 0 , ĠIntent ( PERMISSION ), Ġ 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠU sb Manager . ACTION _ USB _ DEVICE _ DET ACHED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop Thread () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Callback ?. on Device Disconnected () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠmContext . register Receiver ( m Permission Receiver , ĠIntent Filter ( PERMISSION )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġm Reader Ġ= ĠRunnable Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( m Connection Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( m Lock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( m Packet Size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Connection ?. bulk Transfer ( m EndPoint , Ġbuffer , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Packet Size , ĠREAD _ INTERVAL _ M ILL IS )?. let Ġ{ Ġlength Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( length Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= ĠByteArray ( length ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( buffer , Ġ 0 , Ġbytes , Ġ 0 , Ġlength ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Handler . post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Callback ?. on Received ( bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( READ _ INTERVAL _ M ILL IS . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval ĠmContext Ġ= Ġcontext ĊĠĠĠ Ġprivate Ġval Ġm Handler Ġ= ĠHandler () ĊĊĠĠĠ Ġprivate Ġval Ġm Manager Ġ= Ġcontext . getSystem Service ( Context . USB _ SERVICE ) Ġas ĠU sb Manager ĊĠĠĠ Ġprivate Ġvar Ġm Device : ĠU sb Device ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġm Connection : ĠU sb Device Connection ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġm Interface : ĠU sb Interface ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġm EndPoint : ĠU sb Endpoint ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġm Packet Size : ĠInt Ġ= Ġ 0 ĊĊĠĠĠ Ġprivate Ġvar Ġm Read Thread : ĠThread ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġm Lock Ġ= ĠAny () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠU sb Barcode Callback Ġfor ĠU sb H id Reader ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġm Callback : ĠU sb Host Callback ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Suppress (" unused ") ĊĠĠĠ Ġval Ġdevice Name : ĠString ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġm Device ?. product Name ĊĊĠĠĠ Ġ@ Suppress (" unused ") ĊĠĠĠ Ġval ĠisOpen : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġm Device Ġ!= Ġnull ĊĊĠĠĠ Ġ@ Suppress (" unused ") ĊĠĠĠ Ġopen Ġfun Ġopen Device ( callback : ĠU sb Host Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġopen Device ( null , Ġnull , Ġcallback ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġfun Ġopen Device ( vendor Id : ĠInt ? Ġ= Ġnull , ĠproductId : ĠInt ? Ġ= Ġnull , Ġcallback : ĠU sb Host Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Callback Ġ= Ġcallback ĊĊĠĠĠĠĠĠĠ Ġ// ĠGet ĠU sb Device ĠInstance ĊĠĠĠĠĠĠĠ Ġval Ġdevice List Ġ= Ġm Manager . device List ĊĠĠĠĠĠĠĠ Ġdevice List . forEach Ġ{ Ġ_, Ġusb Device Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvendor Id ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ!= Ġusb Device . vendor Id ) Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠproductId ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ!= Ġusb Device . productId ) Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Device Ġ= Ġusb Device ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ forEach ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġm Device ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠmContext . register Receiver ( m Permission Receiver , ĠIntent Filter ( PERMISSION )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠmContext . register Receiver ( m Attach And Detach Receiver , ĠIntent Filter ( Usb Manager . ACTION _ USB _ DEVICE _ ATTACH ED )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠmContext . register Receiver ( m Attach And Detach Receiver , ĠIntent Filter ( Usb Manager . ACTION _ USB _ DEVICE _ DET ACHED )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Manager . request Permission ( it , ĠPending Intent . get Broadcast ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠmContext , Ġ 0 , ĠIntent ( PERMISSION ), Ġ 0 )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" unused ") ĊĠĠĠ Ġfun Ġclose Device () Ġ{ ĊĠĠĠĠĠĠĠ Ġstop Thread () ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠmContext . unregister Receiver ( m Permission Receiver ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠmContext . unregister Receiver ( m Attach And Detach Receiver ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġe . message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġm Callback Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġm Device Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart Thread () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Device ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Connection Ġ= Ġm Manager . open Device ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Interface Ġ= Ġit . get Interface ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm EndPoint Ġ= Ġm Interface ?. get Endpoint ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm EndPoint ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Packet Size Ġ= Ġit . max Packet Size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Connection ?. claim Interface ( m Interface , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Read Thread Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Read Thread Ġ= ĠThread ( m Reader ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Read Thread ?. start () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" thread Ġis Ġalready Ġstarted .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstop Thread () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Read Thread ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Connection ?. let Ġ{ Ġconn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconn . release Interface ( m Interface ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconn . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Connection Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }