package Ġcom . mac ode . kid sd raw ing app čĊč Ċ import Ġandroid . Manifest č Ċ import Ġandroid . app . Activity č Ċ import Ġandroid . app . Dialog č Ċ import Ġandroid . content . Intent č Ċ import Ġandroid . content . pm . PackageManager č Ċ import Ġandroid . graphics . Bitmap č Ċ import Ġandroid . graphics . Canvas č Ċ import Ġandroid . graphics . Color č Ċ import Ġandroid . media . Media Scanner Connection č Ċ import Ġandroidx . appcompat . app . AppCompatActivity č Ċ import Ġandroid . os . Bundle č Ċ import Ġandroid . provider . Media Store č Ċ import Ġandroid . view . View č Ċ import Ġandroid . widget . Image Button č Ċ import Ġandroid . widget . Toast č Ċ import Ġandroidx . core . app . Activity Compat č Ċ import Ġandroidx . core . content . Context Compat č Ċ import Ġandroidx . core . view . get č Ċ import Ġcom . mac ode . kid sd raw ing app . databinding . Activity Main Binding č Ċ import Ġcom . mac ode . kid sd raw ing app . databinding . Dialog Brush Size Binding č Ċ import Ġkotlinx . coroutines . Coroutine Scope č Ċ import Ġkotlinx . coroutines . Dispatch ers . Main č Ċ import Ġkotlinx . coroutines . launch č Ċ import Ġjava . io . File č Ċ import Ġjava . io . File OutputStream č Ċ import Ġjava . io . OutputStream č Ċ import Ġjava . lang . Exception čĊč Ċ class ĠMainActivity Ġ: ĠAppCompatActivity () Ġ{ čĊčĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġbinding : ĠActivity Main Binding čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġbrush Size Binding : ĠDialog Brush Size Binding čĊĠĠĠ Ġprivate Ġvar Ġimage Button Current Paint : ĠImage Button ? Ġ= Ġnull čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġprogress Dialog : ĠDialog čĊčĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ čĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) čĊĠĠĠĠĠĠĠ Ġbinding Ġ= ĠActivity Main Binding . inflate ( layout Inflater ) čĊĠĠĠĠĠĠĠ Ġval Ġview Ġ= Ġbinding . root čĊĠĠĠĠĠĠĠ ĠsetContentView ( view ) čĊčĊĠĠĠĠĠĠĠ Ġbinding . drawing View . setSize For Brush ( 1 0 . toFloat ()) čĊčĊĠĠĠĠĠĠĠ Ġimage Button Current Paint Ġ= Ġbinding . linear Color Palette [ 0 ] Ġas ĠImage Button čĊĠĠĠĠĠĠĠ Ġimage Button Current Paint !!. setImage Drawable ( čĊĠĠĠĠĠĠĠĠĠĠĠ ĠContext Compat . get Drawable ( this , ĠR . drawable . p allet _ selected ) čĊĠĠĠĠĠĠĠ Ġ) čĊčĊĠĠĠĠĠĠĠ Ġbinding . brush . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Brush Size Chooser Dialog () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġbinding . gallery . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Read Storage Allowed ()) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpick Photo Intent Ġ= ĠIntent ( Intent . ACTION _ P ICK , ĠMedia Store . Images . Media . EXTERNAL _ CONTENT _ URI ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartActivity For Result ( pick Photo Intent , ĠG ALL ERY ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Storage Permission () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġbinding . undo . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . onClick Undo () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġbinding . redo . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . onClick Redo () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġbinding . save . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Read Storage Allowed ()) Ġ{ čĊčĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCor outine Scope ( Main ). launch Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Progress Dialog () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Image ( get Bitmap From View ( binding . frame Drawing View Container )) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcancel Progress Dialog () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Storage Permission () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ čĊĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) čĊĠĠĠĠĠĠĠ Ġif Ġ( result Code Ġ== ĠActivity . RESULT _ OK ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( request Code Ġ== ĠG ALL ERY ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( data !!. data Ġ!= Ġnull ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . imageView Background . visibility Ġ= ĠView . VISIBLE čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . imageView Background . setImage URI ( data . data ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this @ MainActivity , Ġ" Error Ġin Ġparsing Ġimage Ġor Ġits Ġcorrupted .", ĠToast . LENGTH _ SHORT ). show () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġfun Ġshow Brush Size Chooser Dialog () Ġ{ čĊĠĠĠĠĠĠĠ Ġbrush Size Binding Ġ= ĠDialog Brush Size Binding . inflate ( layout Inflater ) čĊĠĠĠĠĠĠĠ Ġval Ġview Ġ= Ġbrush Size Binding . root čĊĠĠĠĠĠĠĠ Ġval Ġbrush Dialog Ġ= ĠDialog ( this ) čĊĠĠĠĠĠĠĠ Ġbrush Dialog . set ContentView ( view ) čĊĠĠĠĠĠĠĠ Ġbrush Dialog . setTitle (" Brush Ġsize : Ġ") čĊčĊĠĠĠĠĠĠĠ Ġval Ġextra Small Button Ġ= Ġbrush Size Binding . extra Small Brush čĊĠĠĠĠĠĠĠ Ġval Ġsmall Button Ġ= Ġbrush Size Binding . small Brush čĊĠĠĠĠĠĠĠ Ġval Ġmedium Button Ġ= Ġbrush Size Binding . medium Brush čĊĠĠĠĠĠĠĠ Ġval Ġlarge Button Ġ= Ġbrush Size Binding . large Brush čĊĠĠĠĠĠĠĠ Ġval Ġextra Large Button Ġ= Ġbrush Size Binding . extra Large Brush čĊčĊĠĠĠĠĠĠĠ Ġextra Small Button . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . setSize For Brush ( 5 . toFloat ()) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbrush Dialog . dismiss () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġsmall Button . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . setSize For Brush ( 1 0 . toFloat ()) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbrush Dialog . dismiss () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġmedium Button . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . setSize For Brush ( 1 5 . toFloat ()) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbrush Dialog . dismiss () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġlarge Button . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . setSize For Brush ( 2 0 . toFloat ()) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbrush Dialog . dismiss () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġextra Large Button . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . setSize For Brush ( 2 5 . toFloat ()) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbrush Dialog . dismiss () čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġbrush Dialog . show () čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġfun Ġpaint Clicked ( view : ĠView ) Ġ{ čĊĠĠĠĠĠĠĠ Ġif Ġ( view Ġ!= Ġimage Button Current Paint ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage Button Ġ= Ġview Ġas ĠImage Button čĊčĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcolor Tag Ġ= Ġimage Button . tag . toString () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . drawing View . setColor ( color Tag ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Button . setImage Drawable ( čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext Compat . get Drawable ( this , ĠR . drawable . p allet _ selected ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Button Current Paint !!. setImage Drawable ( čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext Compat . get Drawable ( this , ĠR . drawable . p allet _ normal ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Button Current Paint Ġ= Ġview čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġfun Ġrequest Storage Permission () Ġ{ čĊĠĠĠĠĠĠĠ Ġif Ġ( Activity Compat . should Show Request Permission R ationale ( this , ĠarrayOf ( Manifest . permission . READ _ EXTERNAL _ STORAGE , ĠManifest . permission . WRITE _ EXTERNAL _ STORAGE ). toString ())) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this , Ġ" Need Ġpermission Ġto Ġadd Ġa Ġbackground ", ĠToast . LENGTH _ SHORT ). show () čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ ĠActivity Compat . request Permissions ( this , ĠarrayOf ( Manifest . permission . READ _ EXTERNAL _ STORAGE , ĠManifest . permission . WRITE _ EXTERNAL _ STORAGE ), ĠSTORAGE _ PERMISSION _ CODE ) čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġoverride Ġfun Ġon Request Permissions Result ( čĊĠĠĠĠĠĠĠ Ġrequest Code : ĠInt , čĊĠĠĠĠĠĠĠ Ġpermissions : ĠArray < out ĠString >, čĊĠĠĠĠĠĠĠ Ġgrant Results : ĠInt Array čĊĠĠĠ Ġ) Ġ{ čĊĠĠĠĠĠĠĠ Ġsuper . on Request Permissions Result ( request Code , Ġpermissions , Ġgrant Results ) čĊĠĠĠĠĠĠĠ Ġif Ġ( request Code Ġ== ĠSTORAGE _ PERMISSION _ CODE ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( grant Results . isNotEmpty () Ġ&& Ġgrant Results [ 0 ] Ġ== ĠPackage Manager . PERMISSION _ GRAN TED ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this @ MainActivity , Ġ" Permission Ġgranted , Ġnow Ġyou Ġcan Ġread Ġthe Ġstorage Ġfiles .", ĠToast . LENGTH _ SHORT ). show () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this @ MainActivity , Ġ" Permission Ġdenied !", ĠToast . LENGTH _ SHORT ). show () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġfun Ġis Read Storage Allowed (): ĠBoolean Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠContext Compat . check Self Permission ( this , ĠManifest . permission . READ _ EXTERNAL _ STORAGE ) čĊčĊĠĠĠĠĠĠĠ Ġreturn Ġresult Ġ== ĠPackage Manager . PERMISSION _ GRAN TED čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġfun Ġget Bitmap From View ( view : ĠView ) Ġ: ĠBitmap Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġreturned Bitmap Ġ= ĠBitmap . create Bitmap ( view . width , Ġview . height , ĠBitmap . Config . ARGB _ 8 8 8 8 ) čĊĠĠĠĠĠĠĠ Ġval Ġcanvas Ġ= ĠCanvas ( returned Bitmap ) čĊĠĠĠĠĠĠĠ Ġval Ġbackground Drawable Ġ= Ġview . background čĊĠĠĠĠĠĠĠ Ġif Ġ( background Drawable Ġ!= Ġnull ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Drawable . draw ( canvas ) čĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Color ( Color . WHITE ) čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġview . draw ( canvas ) čĊčĊĠĠĠĠĠĠĠ Ġreturn Ġreturned Bitmap čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsave Image ( image : ĠBitmap ): ĠString ? Ġ{ čĊĠĠĠĠĠĠĠ Ġvar Ġsaved Image Path : ĠString ? Ġ= Ġnull čĊĠĠĠĠĠĠĠ Ġval Ġimage FileName Ġ= Ġ" K id Drawing App _" Ġ+ ĠSystem . currentTimeMillis () Ġ/ Ġ 1 0 0 0 Ġ+ Ġ". png " čĊĠĠĠĠĠĠĠ Ġval Ġstorage Dir Ġ= ĠFile ( external Cache Dir !!. absolute File . toString () Ġ+ ĠFile . separator Ġ+ Ġ" K id Drawing App _" Ġ+ ĠSystem . currentTimeMillis () Ġ/ Ġ 1 0 0 0 Ġ+ Ġ". png ") čĊĠĠĠĠĠĠĠ Ġvar Ġsuccess Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġif Ġ(! storage Dir . exists ()) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġstorage Dir . mkdir s () čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġif Ġ( success ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage File Ġ= ĠFile ( storage Dir , Ġimage FileName ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġsaved Image Path Ġ= Ġimage File . absolute Path čĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf Out : ĠOutputStream Ġ= ĠFileOutputStream ( image File ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage . compress ( Bitmap . Compress Format . PNG , Ġ 1 0 0 , Ġf Out ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġf Out . close () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠĠĠĠĠ Ġgallery Add Image ( saved Image Path ) čĊčĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this , Ġ"$ image FileName Ġsaved !", ĠToast . LENGTH _ SHORT ). show () čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġreturn Ġsaved Image Path čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġfun Ġgallery Add Image ( image Path : ĠString ?) Ġ{ čĊĠĠĠĠĠĠĠ Ġimage Path ?. let Ġ{ Ġpath Ġ-> čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf Ġ= ĠFile ( path ) čĊĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Scanner Connection . scan File ( this @ MainActivity , ĠarrayOf ( f . toString ()), čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ) Ġ{ Ġpath , Ġuri Ġ-> čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshare Intent Ġ= ĠIntent () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshare Intent . action Ġ= ĠIntent . ACTION _ SEND čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshare Intent . putExtra ( Intent . EXTRA _ STREAM , Ġuri ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshare Intent . type Ġ= Ġ" image / png " čĊčĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartActivity ( Intent . create Chooser ( share Intent , Ġ" Share ")) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġshow Progress Dialog () Ġ{ čĊĠĠĠĠĠĠĠ Ġprogress Dialog Ġ= ĠDialog ( this @ MainActivity ) čĊĠĠĠĠĠĠĠ Ġprogress Dialog . set ContentView ( R . layout . dialog _ custom _ progress ) čĊĠĠĠĠĠĠĠ Ġprogress Dialog . show () čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġprivate Ġfun Ġcancel Progress Dialog () Ġ{ čĊĠĠĠĠĠĠĠ Ġprogress Dialog . dismiss () čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġcompanion Ġobject Ġ{ čĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠSTORAGE _ PERMISSION _ CODE Ġ= Ġ 1 čĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠG ALL ERY Ġ= Ġ 2 čĊĠĠĠ Ġ} č Ċ }