package Ġcom . qy tech . k ik ide mo . ui . camera Ċ Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . content . Intent Ċ import Ġandroid . media . Media Scanner Connection Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . Environment Ċ import Ġandroid . view . LayoutInflater Ċ import Ġandroid . view . View Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . webkit . MimeType Map Ċ import Ġandroidx . camera . core .* Ċ import Ġandroidx . camera . lifecycle . Process Camera Provider Ċ import Ġandroidx . camera . view . Camera View Ċ import Ġandroidx . core . content . Context Compat Ċ import Ġandroidx . core . net . to File Ċ import Ġandroidx . fragment . app . Fragment Ċ import Ġandroidx . lifecycle . ViewModel Provider Ċ import Ġandroidx . lifecycle . lifecycle Scope Ċ import Ġandroidx . navigation . Navigation Ċ import Ġcom . qy tech . k ik ide mo . R Ċ import Ġcom . qy tech . k ik ide mo . databinding . Camera Fragment Binding Ċ import Ġcom . qy tech . k ik ide mo . utils . FileUtils Ċ import Ġcom . qy tech . k ik ide mo . utils . L umin osity Analyzer Ċ import Ġcom . qy tech . k ik ide mo . utils . show Toast Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . delay Ċ import Ġkotlinx . coroutines . launch Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . io . File Ċ import Ġjava . text . SimpleDateFormat Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . ExecutorService Ċ import Ġjava . util . concurrent . Executors Ċ import Ġkotlin . math . abs Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ Ċ /** Ċ Ġ* ĠCreated Ġby ĠJ ax Ġon Ġ 2 0 2 1 / 1 / 2 8 . Ċ Ġ* ĠDescription Ġ: Ċ Ġ* ĠVersion Ġ: ĠV 1 . 0 . 0 Ċ Ġ*/ Ċ class ĠCamera Fragment Ġ: ĠFragment () Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġnew Instance () Ġ= ĠCamera Fragment () ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠR AT IO _ 4 _ 3 _ VALUE Ġ= Ġ 4 . 0 Ġ/ Ġ 3 . 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠR AT IO _ 1 6 _ 9 _ VALUE Ġ= Ġ 1 6 . 0 Ġ/ Ġ 9 . 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠFIL ENAME Ġ= Ġ" yyyy - MM - dd - HH - mm - ss " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPH OTO _ EXTENSION Ġ= Ġ". jpg " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠV IDE O _ EXTENSION Ġ= Ġ". mp 4 " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠV IDE O _ DURATION Ġ= Ġ 1 5 _ 0 0 0 L ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar ĠviewModel : ĠCamera ViewModel ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġdata Binding : ĠCamera Fragment Binding ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġpreview : ĠPreview ĊĠĠĠ Ġprivate Ġvar Ġimage Capture : ĠImage Capture ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġvideo Capture : ĠVideo Capture ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġimage Analysis : ĠImage Analysis ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġcamera Executor : ĠExecutor Service ĊĠĠĠ Ġprivate Ġvar Ġcapture Mode : ĠCamera View . Capture Mode ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġis Recording Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġvar Ġcamera Provider : ĠProcess Camera Provider ? Ġ= Ġnull ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate View ( ĊĠĠĠĠĠĠĠ Ġinflater : ĠLayoutInflater , Ġcontainer : ĠViewGroup ?, ĊĠĠĠĠĠĠĠ ĠsavedInstanceState : ĠBundle ? ĊĠĠĠ Ġ): ĠView ? Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Binding Ġ= ĠCamera Fragment Binding . inflate ( in flater , Ġcontainer , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġreturn Ġdata Binding . root ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Activity Created ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Created ( savedInstanceState ) ĊĠĠĠĠĠĠĠ ĠviewModel Ġ= ĠViewModel Provider ( this ). get ( Camera ViewModel :: class . java ) ĊĠĠĠĠĠĠĠ Ġdata Binding . lifecycle Owner Ġ= Ġview Lifecycle Owner ĊĠĠĠĠĠĠĠ Ġdata Binding . viewModel Ġ= ĠviewModel ĊĠĠĠĠĠĠĠ Ġcamera Executor Ġ= ĠExec utors . new Single Thread Executor () ĊĠĠĠĠĠĠĠ Ġdata Binding . view Finder . post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Camera () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdata Binding . btn Take P ictures . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtake Picture () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdata Binding . btn Record Video . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrecord Video () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdata Binding . btn Navigation Main . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNavigation . find Nav Controller ( data Binding . root ). navigate ( R . id . action _ camera _ to _ main ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Destroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Destroy () ĊĠĠĠĠĠĠĠ Ġcamera Executor . shutdown () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart Camera () Ġ{ ĊĠĠĠĠĠĠĠ ĠProcess Camera Provider . getInstance ( require Context ()). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Listener ({ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Provider Ġ= Ġthis . get () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbind Camera User Cases () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĠContext Compat . get Main Executor ( require Context ())) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress Lint (" Restricted Api ") ĊĠĠĠ Ġprivate Ġfun Ġbind Camera User Cases ( mode : ĠCamera View . Capture Mode Ġ= ĠCamera View . Capture Mode . IMAGE ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( capture Mode Ġ== Ġmode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcapture Mode Ġ= Ġmode ĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġscreen Ġmetrics Ġused Ġto Ġsetup Ġcamera Ġfor Ġfull Ġscreen Ġresolution ĊĠĠĠĠĠĠĠ Ġ//// ĠĠĠĠĠĠĠ Ġval Ġmetrics Ġ= ĠDisplay Metrics (). also Ġ{ Ġview Finder . display . get Real Metrics ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ//// ĠĠĠĠĠĠĠ ĠTim ber . d (" Screen Ġmetrics : Ġ${ metrics . width Pixels } Ġx Ġ${ metrics . height Pixels }") ĊĠĠĠĠĠĠĠ Ġ//// ĊĠĠĠĠĠĠĠ Ġ//// ĠĠĠĠĠĠĠ Ġval Ġscreen AspectRatio Ġ= Ġaspect Ratio ( metrics . width Pixels , Ġmetrics . height Pixels ) ĊĠĠĠĠĠĠĠ Ġ//// ĠĠĠĠĠĠĠ ĠTim ber . d (" Preview Ġaspect Ġratio : Ġ$ screen AspectRatio ") ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġval Ġrotation Ġ= Ġview Finder . display . rotation ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ ĠTim ber . d (" bind Camera User Cases Ġmessage : Ġrotation Ġ$ rotation Ġ") ĊĊĠĠĠĠĠĠĠ Ġval Ġcamera Selector Ġ= Ġif Ġ( has Front Camera ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCamera Selector . DEFAULT _ FRONT _ CAMERA ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCamera Selector . DEFAULT _ BACK _ CAMERA ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġpreview Ġ= ĠPreview . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget AspectRatio ( screen AspectRatio ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget Rotation ( rotation ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . set Surface Provider ( data Binding . view Finder . surface Provider ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġimage Capture Ġ= ĠImage Capture . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Capture Mode ( Image Capture . CAPTURE _ MODE _ MAX IM IZE _ QUAL ITY ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget AspectRatio ( screen AspectRatio ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget Rotation ( rotation ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġimage Analysis Ġ= ĠImage Analysis . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget AspectRatio ( screen AspectRatio ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget Rotation ( rotation ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . set Analyzer ( camera Executor , ĠL umin osity Analyzer Ġ{ Ġl uma Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" bind Camera User Cases Ġmessage : Ġ ĠAverage Ġl umin osity Ġ$ l uma ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvideo Capture Ġ= ĠVideo Capture . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget AspectRatio ( screen AspectRatio ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setTarget Rotation ( rotation ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Provider ?. unbind All () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( mode Ġ== ĠCamera View . Capture Mode . IMAGE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Provider ?. bind To Lifecycle ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġview Lifecycle Owner , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Selector , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpreview , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage Capture , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage Analysis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( mode Ġ== ĠCamera View . Capture Mode . VIDEO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Provider ?. bind To Lifecycle ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġview Lifecycle Owner , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Selector , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpreview , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvideo Capture ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress Lint (" Obsolete Sdk Int ") ĊĠĠĠ Ġprivate Ġfun Ġtake Picture () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Recording ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Toast ( R . string . recording ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbind Camera User Cases ( Camera View . Capture Mode . IMAGE ) ĊĠĠĠĠĠĠĠ Ġimage Capture ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġphoto File Ġ= Ġcreate File ( getOutput Directory (), ĠPH OTO _ EXTENSION ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCreate Ġoutput Ġoptions Ġobject Ġwhich Ġcontains Ġfile Ġ+ Ġmetadata ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Options Ġ= ĠImage Capture . OutputFile Options ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. Builder ( photo File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . take Picture ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Options , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Executor , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠImage Capture . On Image Saved Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Image Saved ( outputFile Results : ĠImage Capture . OutputFile Results ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" on Image Saved Ġmessage : Ġ Ġ${ outputFile Results . saved Uri }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Scan File ( outputFile Results . saved Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ< ĠBuild . VERSION _ CODES . N ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Activity (). send Broadcast ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġandroid . hardware . Camera . ACTION _ NEW _ PI CTURE , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputFile Results . saved Uri ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Context (). show Toast ( R . string . image _ saved ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonError ( exception : ĠImage Capture Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" On Image Saved Callback Ġerror Ġ$ exception Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Context (). show Toast ( R . string . image _ saved _ error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress Lint (" Restricted Api ") ĊĠĠĠ Ġprivate Ġfun Ġrecord Video () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Recording ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Toast ( R . string . recording ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbind Camera User Cases ( Camera View . Capture Mode . VIDEO ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvideo Capture ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvideo File Ġ= Ġcreate File ( getOutput Directory (), ĠV IDE O _ EXTENSION ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCreate Ġoutput Ġoptions Ġobject Ġwhich Ġcontains Ġfile Ġ+ Ġmetadata ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Options Ġ= ĠVideo Capture . OutputFile Options ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. Builder ( video File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . start Recording ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Options , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcamera Executor , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠVideo Capture . On Video Saved Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Video Saved ( outputFile Results : ĠVideo Capture . OutputFile Results ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" on Video Saved Ġmessage : Ġ Ġ${ outputFile Results . saved Uri }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Scan File ( outputFile Results . saved Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Context (). show Toast ( R . string . video _ saved ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonError ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvideo Capture Error : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcause : ĠThrowable ? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" On Video Saved Callback Ġerror Ġmessage : Ġ$ message Ġcause : Ġ$ cause ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlifecycle Scope . launch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Context (). show Toast ( R . string . video _ saved _ error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Recording Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( VIDEO _ DURATION ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . stop Recording () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Recording Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ Ġ[ android x . camera . core . Image Analysis Config ] Ġrequires Ġenum Ġvalue Ġof ĊĠĠĠĠ Ġ* Ġ Ġ[ android x . camera . core . AspectRatio ]. ĠCurrently Ġit Ġhas Ġvalues Ġof Ġ 4 : 3 Ġ& Ġ 1 6 : 9 . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ ĠDetect ing Ġthe Ġmost Ġsuitable Ġratio Ġfor Ġdimensions Ġprovided Ġin Ġ@ params Ġby Ġcounting Ġabsolute ĊĠĠĠĠ Ġ* Ġ Ġof Ġpreview Ġratio Ġto Ġone Ġof Ġthe Ġprovided Ġvalues . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġwidth Ġ- Ġpreview Ġwidth ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġheight Ġ- Ġpreview Ġheight ĊĠĠĠĠ Ġ* Ġ Ġ@ return Ġsuitable Ġaspect Ġratio ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġaspect Ratio ( width : ĠInt , Ġheight : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpreview Ratio Ġ= Ġmax ( width , Ġheight ). toDouble () Ġ/ Ġmin ( width , Ġheight ) ĊĠĠĠĠĠĠĠ Ġif Ġ( abs ( preview Ratio Ġ- ĠR AT IO _ 4 _ 3 _ VALUE ) Ġ<= Ġabs ( preview Ratio Ġ- ĠR AT IO _ 1 6 _ 9 _ VALUE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠAs pect Ratio . RATIO _ 4 _ 3 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠAs pect Ratio . RATIO _ 1 6 _ 9 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Back Camera (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcamera Provider ?. has Camera ( Camera Selector . DEFAULT _ BACK _ CAMERA ) Ġ== Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Front Camera (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcamera Provider ?. has Camera ( Camera Selector . DEFAULT _ FRONT _ CAMERA ) Ġ== Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Output Directory (): ĠFile Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstorage Path Ġ= ĠFileUtils . get Storage Path ( require Context ()) ĊĠĠĠĠĠĠĠ Ġval Ġoutput Path Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( storage Path ?. isNotBlank () Ġ== Ġtrue ) Ġstorage Path Ġelse ĠEnvironment . get External Storage Directory (). absolute Path ĊĠĠĠĠĠĠĠ Ġreturn ĠFile ( output Path , ĠgetString ( R . string . app _ name )). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! it . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . mkdir s () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĠHelper Ġfunction Ġused Ġto Ġcreate Ġa Ġtimestamp ed Ġfile Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcreate File ( base Folder : ĠFile , Ġextension : ĠString ) Ġ= ĊĠĠĠĠĠĠĠ ĠFile ( base Folder , Ġ"${ format Date ()} _${ extension }") ĊĊĠĠĠ Ġprivate Ġfun Ġformat Date () Ġ= ĠSimpleDateFormat ( FILENAME , ĠLocale . getDefault ()) ĊĠĠĠĠĠĠĠ Ġ. format ( System . currentTimeMillis ()) ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Scan File ( uri : ĠUri ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠmimeType Ġ= ĠMime TypeMap . get Singleton () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get MimeType From Extension ( uri ?. to File ()?. extension ) ĊĠĠĠĠĠĠĠ ĠMedia Scanner Connection . scan File ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( uri ?. to File ()?. absolute Path ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( mime Type ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġ_, Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" notify Scan File Ġscanned Ġinto Ġmedia Ġstore : Ġ$ uri ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }