/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 1 ĠImage ĠP icker Ċ Ġ* ĠAuthor : ĠN gu yen ĠHo ang ĠL am Ġ< ho ang lam vn 9 0 @ gmail . com > Ċ Ġ*/ Ċ Ċ package Ġcom . ng uy en ho ang lam . image picker . ui . camera Ċ Ċ import Ġandroid . content . Content Resolver Ċ import Ġandroid . content . Content Values Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . pm . PackageManager Ċ import Ġandroid . graphics . Bitmap Ċ import Ġandroid . graphics . Bitmap Factory Ċ import Ġandroid . media . Media Scanner Connection Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Environment Ċ import Ġandroid . provider . Media Store Ċ import Ġandroidx . core . content . File Provider Ċ import Ġcom . ng uy en ho ang lam . image picker . helper . Device Helper Ċ import Ġcom . ng uy en ho ang lam . image picker . model . Image Ċ import Ġcom . ng uy en ho ang lam . image picker . model . Image Picker Config Ċ import Ġcom . ng uy en ho ang lam . image picker . model . Root Directory Ċ import Ġjava . io . File Ċ import Ġjava . io . IOException Ċ import Ġjava . io . Serializable Ċ import Ġjava . text . SimpleDateFormat Ċ import Ġjava . util .* Ċ import Ġandroid . graphics . Matrix Ċ import Ġandroidx . ex if interface . media . Ex if Interface ĊĊ Ċ class ĠCamera Module Ġ: ĠSerializable Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠSU FF IX Ġ= Ġ". jpg " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġcurrent File Uri : ĠUri ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcurrent FilePath : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcurrent FileName : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġfun Ġget Camera Intent ( context : ĠContext , Ġconfig : ĠImage Picker Config ): ĠIntent ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠIntent ( Media Store . ACTION _ IMAGE _ CAPTURE ) ĊĊĠĠĠĠĠĠĠ Ġval Ġimage File Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Image File ( context , Ġconfig . root Directory . value , Ġconfig . sub Directory !! ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( image File Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprovider Name Ġ= Ġcontext . packageName Ġ+ Ġ". file provider " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage Uri : ĠUri Ġ= ĠFile Provider . get Uri For File ( context , Ġprovider Name , Ġimage File ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġintent . putExtra ( Media Store . EXTRA _ OUTPUT , Ġimage Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġintent . add Flags ( Intent . FLAG _ GRANT _ READ _ URI _ PERMISSION Ġor ĠIntent . FLAG _ GRANT _ WRITE _ URI _ PERMISSION ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrant App Permission ( context , Ġintent , Ġimage Uri ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent File Uri Ġ= Ġimage Uri ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent FilePath Ġ= Ġimage File . absolute Path ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġintent ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" DE PREC ATION ") ĊĠĠĠ Ġprivate Ġfun Ġcreate Image File ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠ Ġroot Directory : ĠString , ĊĠĠĠĠĠĠĠ Ġsub Directory : ĠString ĊĠĠĠ Ġ): ĠFile ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġroot Dir : ĠFile ? Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Device Helper . is Min Sdk 2 9 ) Ġcontext . get External Files Dir ( root Directory ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠEnvironment . get External Storage Public Directory ( root Directory ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( rootDir Ġ== Ġnull ) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġstorage Dir Ġ= ĠFile ( rootDir , Ġsub Directory ) ĊĠĠĠĠĠĠĠ Ġvar Ġis Dir Exist ed Ġ= Ġstorage Dir . exists () ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Dir Exist ed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Dir Exist ed Ġ= Ġstorage Dir . mkdir s () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( is Dir Exist ed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Stamp : ĠString Ġ= ĠSimpleDateFormat (" yyyy MM dd _ HH mm ss "). format ( Date ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Prefix Ġ= Ġ" IMG _${ time Stamp }_ " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent FileName Ġ= Ġfile Prefix ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFile . create TempFile ( file Prefix , ĠSU FF IX , Ġstorage Dir ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" DE PREC ATION ") ĊĠĠĠ Ġfun Ġsave Image ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠ Ġconfig : ĠImage Picker Config , ĊĠĠĠĠĠĠĠ Ġimage Ready Listener : ĠOn Image Ready Listener ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( current File Uri Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Ready Listener . on Image Not Ready () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( context ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcontent Resolver Ġ= Ġcontext . content Resolver ĊĠĠĠĠĠĠĠ Ġvar Ġnew File Uri : ĠUri ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Device Helper . is Min Sdk 2 9 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Stamp : ĠString Ġ= ĠSimpleDateFormat (" yyyy MM dd _ HH mm ss "). format ( Date ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Prefix Ġ= Ġ" IMG _${ time Stamp }_ " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfileName Ġ= Ġfile Prefix Ġ+ ĠSU FF IX ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrelative Path Ġ= Ġconfig . root Directory . value Ġ+ ĠFile . separator Ġ+ Ġconfig . sub Directory ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent FileName Ġ= Ġfile Prefix ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠContent Values (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( Media Store . Images . Media . DISPLAY _ NAME , ĠfileName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( Media Store . Images . Media . MIME _ TYPE , Ġ" image / jpeg ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( Media Store . Images . Media . REL ATIVE _ PATH , Ġrelative Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= Ġget Bitmap From Uri ( content Resolver , Ġcurrent File Uri !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrotated Bitmap Ġ= Ġrotate Bitmap ( bitmap , Ġcurrent FilePath !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Resolver . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġurl Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( config . root Directory Ġ== ĠRoot Directory . DOWNLOAD S ) ĠMedia Store . Downloads . EXTERNAL _ CONTENT _ URI ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠMedia Store . Images . Media . EXTERNAL _ CONTENT _ URI ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew File Uri Ġ= Ġcontent Resolver . insert ( url , Ġvalues ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new File Uri Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage OutputStream Ġ= Ġopen OutputStream ( new File Uri !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrotated Bitmap ?. compress ( Bitmap . Compress Format . JPEG , Ġ 1 0 0 , Ġimage OutputStream ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimages Ġ= Ġarray ListOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠImage ( new File Uri !! , Ġcurrent FileName !! , Ġ 0 , Ġconfig . sub Directory !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage Ready Listener . on Image Ready ( images ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage Ready Listener . on Image Not Ready () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Scanner Connection . scan File ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( current FilePath ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ Ġpath , Ġuri Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= Ġget Bitmap From Uri ( content Resolver , Ġuri ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrotated Bitmap Ġ= Ġrotate Bitmap ( bitmap , Ġpath ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Resolver . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage OutputStream Ġ= Ġopen OutputStream ( uri !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrotated Bitmap ?. compress ( Bitmap . Compress Format . JPEG , Ġ 1 0 0 , Ġimage OutputStream ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimages Ġ= Ġarray ListOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠImage ( uri !! , Ġcurrent FileName !! , Ġ 0 , Ġconfig . sub Directory !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage Ready Listener . on Image Ready ( images ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew File Uri ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Resolver . delete ( it , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Ready Listener . on Image Not Ready () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( context ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġreset ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Device Helper . is Min Sdk 2 9 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelete File From Uri ( context , Ġcurrent File Uri !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġre voke App Permission ( context , Ġcurrent File Uri !! ) ĊĠĠĠĠĠĠĠ Ġcurrent File Uri Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġcurrent FilePath Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġcurrent FileName Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdelete File From Uri ( context : ĠContext , Ġuri : ĠUri ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . delete ( uri , Ġnull , Ġnull ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgrant App Permission ( context : ĠContext , Ġintent : ĠIntent , Ġfile Uri : ĠUri ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresolved Intent Activities Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . package Manager . query Intent Activities ( intent , ĠPackage Manager . MATCH _ DEFAULT _ ONLY ) ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( resolved Intent Info Ġin Ġresolved Intent Activities ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠpackageName Ġ= Ġresolved Intent Info . activity Info . packageName ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . grant Uri Permission ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠpackageName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Uri , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent . FLAG _ GRANT _ WRITE _ URI _ PERMISSION Ġor ĠIntent . FLAG _ GRANT _ READ _ URI _ PERMISSION ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġre voke App Permission ( context : ĠContext , Ġfile Uri : ĠUri ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext . revoke Uri Permission ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile Uri , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIntent . FLAG _ GRANT _ WRITE _ URI _ PERMISSION Ġor ĠIntent . FLAG _ GRANT _ READ _ URI _ PERMISSION ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Bitmap From Uri ( content Resolver : ĠContent Resolver , Ġuri : ĠUri ): ĠBitmap Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġcontent Resolver . open InputStream ( uri ) ĊĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= ĠBitmap Factory . decode Stream ( inputStream ) ĊĠĠĠĠĠĠĠ ĠinputStream ?. close () ĊĠĠĠĠĠĠĠ Ġreturn Ġbitmap ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġex if To Degrees ( path : ĠString ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrotation : ĠInt Ġ= ĠEx if Interface ( path ). getAttribute Int ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . TAG _ OR IENTATION , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ NORMAL ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( rotation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 9 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 9 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 1 8 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 8 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 2 7 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 2 7 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 f ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrotate Bitmap ( source : ĠBitmap , Ġpath : ĠString ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmatrix Ġ= ĠMatrix () ĊĠĠĠĠĠĠĠ Ġmatrix . post Rotate ( ex if To Degrees ( path )) ĊĠĠĠĠĠĠĠ Ġreturn ĠBitmap . create Bitmap ( source , Ġ 0 , Ġ 0 , Ġsource . width , Ġsource . height , Ġmatrix , Ġtrue ) ĊĠĠĠ Ġ} Ċ Ċ }