/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 9 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 . Ċ Ġ*/ Ċ Ċ package Ġcom . android . samples . medi astore Ċ Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . app . Application Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . app . Recover able Security Exception Ċ import Ġandroid . content . Content Provider Ċ import Ġandroid . content . Content Resolver Ċ import Ġandroid . content . Content U ris Ċ import Ġandroid . content . Intent Sender Ċ import Ġandroid . database . Content Observer Ċ import Ġandroid . database . Cursor Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Looper Ċ import Ġandroid . provider . Media Store Ċ import Ġandroid . util . Log Ċ import Ġandroidx . activity . result . Activity Result Launcher Ċ import Ġandroidx . activity . result . Intent Sender Request Ċ import Ġandroidx . lifecycle . Android ViewModel Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġandroidx . recyclerview . widget . ListAdapter Ċ import Ġandroidx . recyclerview . widget . RecyclerView Ċ import Ġcom . google . android . material . dialog . Material AlertDialog Builder Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġjava . text . SimpleDateFormat Ċ import Ġjava . util . Date Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . coroutines . Coroutine Context Ċ Ċ /** Ċ Ġ* ĠThe Ġ[ Android ViewModel ] Ġview Ġmodel Ġused Ġby Ġour Ġapplication . Ċ Ġ*/ Ċ class ĠMainActivity ViewModel ( application : ĠApplication ) Ġ: ĠAndroid ViewModel ( application ) Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Mutable LiveData ] Ġwrapped Ġ[ List ] Ġof Ġ[ Media Store Image ] Ġthat Ġserves Ġas Ġour Ġdataset . ĠPrivate ĊĠĠĠĠ Ġ* Ġto Ġprevent Ġother Ġclasses Ġfrom Ġchanging Ġit , Ġread - only Ġaccess Ġis Ġprovided Ġby Ġour Ġ[ images ] Ġfield . ĊĠĠĠĠ Ġ* ĠOur Ġ[ load Images ] Ġmethod Ġposts Ġthe Ġ[ List ] Ġof Ġ[ Media Store Image ] Ġobjects Ġthat Ġour Ġ[ query Images ] ĊĠĠĠĠ Ġ* Ġmethod Ġbuilds Ġfrom Ġthe Ġ[ Cursor ] Ġreturned Ġfrom Ġthe Ġ[ Content Resolver . query ] Ġmethod Ġfor Ġthe Ġ[ Uri ] ĊĠĠĠĠ Ġ* Ġ[ Media Store . Images . Media . EXTERNAL _ CONTENT _ URI ] Ġ(" content :// media / external / images / media "). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ images Ġ= ĠMutable LiveData < List < Media Store Image >>() ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPublic Ġread - only Ġaccess Ġto Ġour Ġ[_ images ] Ġfield . ĠAn Ġobserver Ġis Ġadded Ġto Ġit Ġin Ġthe Ġ` onCreate ` ĊĠĠĠĠ Ġ* Ġoverride Ġof Ġ[ MainActivity ] Ġwhose Ġlambda Ġcalls Ġthe Ġ[ ListAdapter . submit List ] Ġmethod Ġof Ġthe ĊĠĠĠĠ Ġ* Ġ` Gallery Adapter ` Ġfeed ing Ġviews Ġto Ġits Ġ[ RecyclerView ] Ġwith Ġthe Ġ[ List ] Ġvalue Ġwhenever Ġit Ġchanges ĊĠĠĠĠ Ġ* Ġvalue . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġimages : ĠLive Data < List < Media Store Image >> Ġget () Ġ= Ġ_ images ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Content Observer ] Ġwe Ġregister Ġin Ġour Ġ[ load Images ] Ġmethod Ġto Ġreceive Ġcall Ġback s Ġfor Ġany ĊĠĠĠĠ Ġ* Ġchanges Ġthat Ġoccur Ġin Ġthe Ġcontent Ġof Ġthe Ġ` Uri ` Ġ[ Media Store . Images . Media . EXTERNAL _ CONTENT _ URI ] ĊĠĠĠĠ Ġ* Ġ(" content :// media / external / images / media "). ĠThe Ġlambda Ġthat Ġis Ġexecuted Ġwhen Ġthis Ġoccurs Ġis ĊĠĠĠĠ Ġ* Ġa Ġcall Ġto Ġ[ load Images ] Ġto Ġreload Ġour Ġdataset . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġcontent Observer : ĠContent Observer ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhen Ġan Ġattempt Ġto Ġdelete Ġan Ġimage Ġfails Ġbecause Ġof Ġa Ġ[ Security Exception ] Ġthis Ġserves Ġas Ġa ĊĠĠĠĠ Ġ* Ġsignal Ġto Ġthe ĠActivity Ġthat Ġit Ġneeds Ġto Ġrequest Ġpermission Ġand Ġtry Ġthe Ġdelete Ġagain Ġif ĊĠĠĠĠ Ġ* Ġpermission Ġis Ġgranted . ĠIt Ġis Ġset Ġto Ġthe Ġ[ Media Store Image ] Ġargument Ġto Ġour Ġ[ perform Delete Image ] ĊĠĠĠĠ Ġ* Ġmethod Ġwhen Ġthe Ġmethod Ġcat ches Ġ[ Security Exception ] Ġwhen Ġit Ġtries Ġto Ġdelete Ġthe Ġimage Ġusing ĊĠĠĠĠ Ġ* Ġthe Ġ[ Content Resolver . delete ] Ġmethod . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġpending Delete Image : ĠMedia Store Image ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġ[ Mutable LiveData ] Ġwrapped Ġ[ Intent Sender ] Ġis Ġbuilt Ġto Ġhold Ġthe Ġ[ Pending Intent ] Ġthat Ġthe ĊĠĠĠĠ Ġ* Ġ[ Recover able Security Exception ] Ġsuggests Ġas Ġthe Ġprimary Ġaction Ġto Ġinvolve Ġthe Ġend Ġuser Ġto ĊĠĠĠĠ Ġ* Ġrecover Ġfrom Ġthe Ġexception . ĠIt Ġis Ġset Ġby Ġour Ġ[ perform Delete Image ] Ġmethod Ġwhen Ġit Ġcat ches Ġa ĊĠĠĠĠ Ġ* Ġ[ Recover able Security Exception ] Ġto Ġa Ġ[ Intent Sender ] Ġobject Ġthat Ġwraps Ġthe Ġexisting Ġsender Ġof ĊĠĠĠĠ Ġ* Ġthe Ġ[ Pending Intent ] Ġthat Ġis Ġthe Ġaction Ġintent Ġof Ġthe Ġprimary Ġaction Ġthat Ġwill Ġinitiate Ġthe ĊĠĠĠĠ Ġ* Ġrecovery Ġfrom Ġthe Ġ[ Recover able Security Exception ]. ĠIt Ġis Ġprivate Ġto Ġprevent Ġother Ġclasses Ġfrom ĊĠĠĠĠ Ġ* Ġmodifying Ġit , Ġpublic Ġread - only Ġaccess Ġis Ġprovided Ġby Ġour Ġ[ permission Needed For Delete ] Ġfield . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ permission Needed For Delete Ġ= ĠMutable LiveData < Intent Sender ?> () ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPublic Ġread - only Ġaccess Ġto Ġour Ġ[_ permission Needed For Delete ] Ġfield . ĠAn Ġobserver Ġis Ġadded Ġto Ġit ĊĠĠĠĠ Ġ* Ġin Ġthe Ġ` onCreate ` Ġoverride Ġof Ġ[ MainActivity ] Ġwhose Ġlambda Ġla unches Ġthe Ġactivity Ġdescribed Ġby ĊĠĠĠĠ Ġ* Ġthe Ġ[ Intent Sender ] Ġfor Ġits Ġresult Ġwhenever Ġit Ġchanges Ġto Ġa Ġnon - ` null ` Ġvalue . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpermission Needed For Delete : ĠLive Data < Intent Sender ?> Ġ= Ġ_ permission Needed For Delete ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPerforms Ġa Ġone Ġshot Ġload Ġof Ġimages Ġfrom Ġ[ Media Store . Images . Media . EXTERNAL _ CONTENT _ URI ] Ġinto ĊĠĠĠĠ Ġ* Ġour Ġ[ LiveData ] Ġwrapped Ġ[ List ] Ġof Ġ[ Media Store Image ] Ġfield Ġ[_ images ]. ĠWe Ġlaunch Ġa Ġnew Ġcoroutine ĊĠĠĠĠ Ġ* Ġwithout Ġblocking Ġthe Ġcurrent Ġthread Ġusing Ġthe Ġ[ Coroutine Scope ] Ġtied Ġto Ġthis Ġ` ViewModel `. ĠThe ĊĠĠĠĠ Ġ* Ġcoroutine Ġblock Ġconsists Ġof Ġa Ġlambda Ġwhich : ĊĠĠĠĠ Ġ* Ġ Ġ- ĠInitializes Ġour Ġ[ List ] Ġof Ġ[ Media Store Image ] Ġvariable Ġ` val Ġimage List ` Ġto Ġthe Ġ[ List ] Ġreturned ĊĠĠĠĠ Ġ* Ġ Ġby Ġour Ġ[ query Images ] Ġmethod Ġwhen Ġit Ġqueries Ġa Ġ[ Content Resolver ] Ġinstance Ġfor Ġour Ġapplication 's ĊĠĠĠĠ Ġ* Ġ Ġpackage Ġfor Ġthe Ġ[ Media Store . Images . Media . EXTERNAL _ CONTENT _ URI ] Ġcontent Ġ[ Uri ] Ġand Ġbuilds Ġa ĊĠĠĠĠ Ġ* Ġ Ġ[ Media Store Image ] Ġobject Ġfor Ġeach Ġof Ġthe Ġrows Ġof Ġthe Ġ[ Cursor ] Ġreturned . ĊĠĠĠĠ Ġ* Ġ Ġ- ĠPosts Ġa Ġtask Ġto Ġa Ġmain Ġthread Ġto Ġset Ġvalue Ġof Ġour Ġ[ Mutable LiveData ] Ġwrapped Ġ[ List ] Ġof ĊĠĠĠĠ Ġ* Ġ Ġ[ Media Store Image ] Ġfield Ġ[_ images ] Ġto Ġ` image List `. ĊĠĠĠĠ Ġ* Ġ Ġ- ĠIf Ġour Ġ[ Content Observer ] Ġfield Ġ[ content Observer ] Ġis Ġ` null ` Ġwe Ġset Ġit Ġto Ġan Ġinstance Ġthat ĊĠĠĠĠ Ġ* Ġ Ġis Ġregistered Ġto Ġobserve Ġ[ Media Store . Images . Media . EXTERNAL _ CONTENT _ URI ] Ġfor Ġchanges Ġand Ġto ĊĠĠĠĠ Ġ* Ġ Ġexecute Ġa Ġlambda Ġwhich Ġcalls Ġthis Ġ[ load Images ] Ġmethod Ġagain Ġwhen Ġthe Ġcontent Ġof Ġthe Ġ[ Uri ] ĊĠĠĠĠ Ġ* Ġ Ġchanges . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġis Ġcalled Ġfrom Ġthe Ġ` show Images ` Ġmethod Ġof Ġ[ MainActivity ], Ġand Ġby Ġthe Ġ[ Content Observer ] ĊĠĠĠĠ Ġ* Ġthat Ġwe Ġregister . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġload Images () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage List : ĠList < Media Store Image > Ġ= Ġquery Images () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ images . post Value ( image List ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( content Observer Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Observer Ġ= Ġget Application < Application >(). content Resolver . register Observer ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Store . Images . Media . EXTERNAL _ CONTENT _ URI ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Images () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRequests Ġthe Ġ[ Media Store ] Ġto Ġdelete Ġthe Ġimage Ġassociated Ġwith Ġour Ġ[ Media Store Image ] Ġparameter ĊĠĠĠĠ Ġ* Ġ[ image ]. ĠWe Ġlaunch Ġa Ġnew Ġcoroutine Ġwithout Ġblocking Ġthe Ġcurrent Ġthread Ġusing Ġthe Ġ[ Coroutine Scope ] ĊĠĠĠĠ Ġ* Ġtied Ġto Ġthis Ġ` ViewModel `. ĠThe Ġcoroutine Ġblock Ġconsists Ġof Ġa Ġlambda Ġwhich Ġcalls Ġour Ġ` suspend ` ĊĠĠĠĠ Ġ* Ġfunction Ġ[ perform Delete Image ] Ġwith Ġour Ġparameter Ġ[ image ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIt Ġis Ġcalled Ġfrom Ġour Ġ[ delete Pending Image ] Ġmethod Ġand Ġfrom Ġthe Ġ[ Material AlertDialog Builder ] ĊĠĠĠĠ Ġ* Ġshown Ġby Ġthe Ġ` delete Image ` Ġmethod Ġof Ġ[ MainActivity ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġimage Ġthe Ġ[ Media Store Image ] Ġcontaining Ġthe Ġinformation Ġneeded Ġto Ġdelete Ġthe Ġimage Ġ( the ĊĠĠĠĠ Ġ* ĠURL Ġof Ġthe Ġrow Ġto Ġdelete Ġis Ġin Ġits Ġ[ Media Store Image . content Uri ] Ġproperty , Ġand Ġits Ġ`_ ID ` Ġis Ġin ĊĠĠĠĠ Ġ* Ġin Ġits Ġ[ Media Store Image . id ] Ġproperty ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġdelete Image ( image : ĠMedia Store Image ) Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġperform Delete Image ( image ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġis Ġcalled Ġupon Ġsuccessful Ġreturn Ġfrom Ġthe Ġactivity Ġlaunched Ġto Ġhave Ġthe Ġsystem ĊĠĠĠĠ Ġ* Ġask Ġthe Ġuser Ġfor Ġpermission Ġto Ġdelete Ġthe Ġfile Ġassociated Ġwith Ġthe Ġ[ Media Store Image ] Ġfield ĊĠĠĠĠ Ġ* Ġ[ pending Delete Image ]. ĠIf Ġ[ pending Delete Image ] Ġis Ġnot Ġ` null ` Ġwe Ġuse Ġthe Ġ[ let ] Ġextension ĊĠĠĠĠ Ġ* Ġfunction Ġto Ġset Ġit Ġto Ġ` null ` Ġand Ġto Ġcall Ġour Ġ[ delete Image ] Ġmethod Ġto Ġdelete Ġthe Ġimage ĊĠĠĠĠ Ġ* Ġassociated Ġwith Ġit . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIt Ġis Ġcalled Ġin Ġthe Ġlambda Ġof Ġthe Ġ[ Activity Result Launcher ] Ġof Ġ[ Intent Sender Request ] Ġthat Ġis ĊĠĠĠĠ Ġ* Ġregistered Ġto Ġinitialize Ġthe Ġ` request Permission ToDelete ` Ġfield Ġof Ġ[ MainActivity ], Ġand Ġthat ĊĠĠĠĠ Ġ* Ġ[ Activity Result Launcher ] Ġis Ġlaunched Ġby Ġan Ġobserver Ġof Ġour Ġ[ permission Needed For Delete ] Ġfield ĊĠĠĠĠ Ġ* Ġwhen Ġit Ġchanges Ġto Ġa Ġnon - ` null ` Ġvalue . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġdelete Pending Image () Ġ{ ĊĠĠĠĠĠĠĠ Ġpending Delete Image ?. let Ġ{ Ġimage Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending Delete Image Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelete Image ( image ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠQueries Ġa Ġ[ Content Resolver ] Ġinstance Ġfor Ġour Ġapplication 's Ġpackage Ġfor Ġall Ġof Ġthe Ġimages Ġthat ĊĠĠĠĠ Ġ* Ġthe Ġ[ Media Store . Images . Media . EXTERNAL _ CONTENT _ URI ] Ġcontent Ġ[ Uri ] Ġreturns Ġin Ġits Ġ[ Cursor ] Ġand ĊĠĠĠĠ Ġ* Ġconverts Ġthat Ġ[ Cursor ] Ġto Ġa Ġ[ List ] Ġof Ġ[ Media Store Image ] Ġobjects Ġwhich Ġit Ġreturns . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġ[ List ] Ġof Ġ[ Media Store Image ] Ġobjects Ġwhich Ġcan Ġbe Ġused Ġto Ġreference Ġall Ġof Ġthe Ġimages ĊĠĠĠĠ Ġ* Ġthat Ġ[ Media Store ] Ġis Ġaware Ġof . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġquery Images (): ĠList < Media Store Image > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġimages Ġ= Ġmutable ListOf < Media Store Image >() ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWorking Ġwith Ġ[ Content Resolver ] s Ġcan Ġbe Ġslow , Ġso Ġwe 'll Ġdo Ġthis Ġoff Ġthe Ġmain ĊĠĠĠĠĠĠĠĠ Ġ* Ġthread Ġinside Ġa Ġcoroutine . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠA Ġkey Ġconcept Ġwhen Ġworking Ġwith ĠAndroid Ġ[ Content Provider ] s Ġis Ġsomething Ġcalled ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġ" projection s ". ĠA Ġprojection Ġis Ġthe Ġlist Ġof Ġcolumns Ġto Ġrequest Ġfrom Ġthe Ġprovider , ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġand Ġcan Ġbe Ġthought Ġof Ġ( qu ite Ġaccur ately ) Ġas Ġthe Ġ" SELECT Ġ..." Ġclause Ġof Ġa ĠSQL ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġstatement . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIt 's Ġnot Ġ_ required _ Ġto Ġprovide Ġa Ġprojection . ĠIn Ġthis Ġcase , Ġone Ġcould Ġpass Ġ` null ` ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġin Ġplace Ġof Ġ` projection ` Ġin Ġthe Ġcall Ġto Ġ[ Content Resolver . query ], Ġbut Ġrequesting ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġmore Ġdata Ġthan Ġis Ġrequired Ġhas Ġa Ġperformance Ġimpact . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠFor Ġthis Ġsample , Ġwe Ġonly Ġuse Ġa Ġfew Ġcolumns Ġof Ġdata , Ġand Ġso Ġwe 'll Ġrequest Ġjust Ġa ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġsubset Ġof Ġcolumns . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprojection Ġ= ĠarrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Store . Images . Media ._ ID , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Store . Images . Media . DISPLAY _ NAME , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Store . Images . Media . DATE _ AD DED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġ` selection ` Ġis Ġthe Ġ" WHERE Ġ..." Ġclause Ġof Ġa ĠSQL Ġstatement . ĠIt 's Ġalso Ġpossible ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġto Ġomit Ġthis Ġby Ġpassing Ġ` null ` Ġin Ġits Ġplace , Ġand Ġthen Ġall Ġrows Ġwill Ġbe Ġreturned . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIn Ġthis Ġcase Ġwe 're Ġusing Ġa Ġselection Ġbased Ġon Ġthe Ġdate Ġthe Ġimage Ġwas Ġtaken . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠNote Ġthat Ġwe 've Ġincluded Ġa Ġ` ?` Ġin Ġour Ġselection . ĠThis Ġstands Ġin Ġfor Ġa Ġvariable ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġwhich Ġwill Ġbe Ġprovided Ġby Ġthe Ġnext Ġvariable . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"${ Media Store . Images . Media . DATE _ AD DED } Ġ>= Ġ? " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġ` selection Args ` Ġis Ġa Ġlist Ġof Ġvalues Ġthat Ġwill Ġbe Ġfilled Ġin Ġfor Ġeach Ġ` ?` ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġin Ġthe Ġ` selection `. ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġselection Args Ġ= ĠarrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRelease Ġday Ġof Ġthe ĠG 1 . Ġ:) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdate To Timestamp ( day Ġ= Ġ 2 2 , Ġmonth Ġ= Ġ 1 0 , Ġyear Ġ= Ġ 2 0 0 8 ). toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠSort Ġorder Ġto Ġuse . ĠThis Ġcan Ġalso Ġbe Ġnull , Ġwhich Ġwill Ġuse Ġthe Ġdefault Ġsort ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġorder . ĠFor Ġ[ Media Store . Images ], Ġthe Ġdefault Ġsort Ġorder Ġis Ġascending Ġby Ġdate Ġtaken . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsort Order Ġ= Ġ"${ Media Store . Images . Media . DATE _ AD DED } ĠDESC " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Application < Application >(). content Resolver . query ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Store . Images . Media . EXTERNAL _ CONTENT _ URI , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprojection , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselection , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselection Args , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsort Order ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ?. use Ġ{ Ġcursor : ĠCursor Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIn Ġorder Ġto Ġretrieve Ġthe Ġdata Ġfrom Ġthe Ġ[ Cursor ] Ġthat 's Ġreturned , Ġwe Ġneed Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġfind Ġwhich Ġindex Ġmatches Ġeach Ġcolumn Ġthat Ġwe 're Ġinterested Ġin . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThere Ġare Ġtwo Ġways Ġto Ġdo Ġthis . ĠThe Ġfirst Ġis Ġto Ġuse Ġthe Ġmethod ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġ[ Cursor . getColumnIndex ] Ġwhich Ġreturns Ġ- 1 Ġif Ġthe Ġcolumn ĠID Ġisn 't Ġfound . ĠThis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġis Ġuseful Ġif Ġthe Ġcode Ġis Ġprogram matically Ġchoosing Ġwhich Ġcolumns Ġto Ġrequest , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġbut Ġwould Ġlike Ġto Ġuse Ġa Ġsingle Ġmethod Ġto Ġparse Ġthem Ġinto Ġobjects . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIn Ġour Ġcase , Ġsince Ġwe Ġknow Ġexactly Ġwhich Ġcolumns Ġwe 'd Ġlike , Ġand Ġwe Ġknow ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġthat Ġthey Ġmust Ġbe Ġincluded Ġ( since Ġthey 're Ġall Ġsupported Ġfrom ĠAPI Ġ 1 ), Ġwe 'll ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġuse Ġ[ Cursor . getColumnIndex OrThrow ]. ĠThis Ġmethod Ġwill Ġthrow Ġan ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġ[ IllegalArgumentException ] Ġif Ġthe Ġcolumn Ġnamed Ġisn 't Ġfound . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIn Ġeither Ġcase , Ġwhile Ġthis Ġmethod Ġisn 't Ġslow , Ġwe 'll Ġwant Ġto Ġcache Ġthe Ġresults ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġto Ġavoid Ġhaving Ġto Ġlook Ġthem Ġup Ġfor Ġeach Ġrow . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Column Ġ= Ġcursor . getColumnIndex OrThrow ( Media Store . Images . Media ._ ID ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdate Modified Column Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor . getColumnIndex OrThrow ( Media Store . Images . Media . DATE _ AD DED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠdisplayName Column Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor . getColumnIndex OrThrow ( Media Store . Images . Media . DISPLAY _ NAME ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Found Ġ${ cursor . count } Ġimages ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( cursor . moveTo Next ()) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHere Ġwe 'll Ġuse Ġthe Ġcolumn Ġindex s Ġthat Ġwe Ġfound Ġabove . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġcursor . getLong ( id Column ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdate Modified Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDate ( TimeUnit . SECONDS . to Millis ( cursor . getLong ( date Modified Column ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠdisplayName Ġ= Ġcursor . getString ( displayName Column ) ĊĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThis Ġis Ġone Ġof Ġthe Ġtrick iest Ġparts : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠSince Ġwe 're Ġaccessing Ġimages Ġ( using ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġ[ Media Store . Images . Media . EXTERNAL _ CONTENT _ URI ], Ġwe 'll Ġuse Ġthat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġas Ġthe Ġbase ĠURI Ġand Ġappend Ġthe ĠID Ġof Ġthe Ġimage Ġto Ġit . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThis Ġis Ġthe Ġexact Ġsame Ġway Ġto Ġdo Ġit Ġwhen Ġworking Ġwith Ġ[ Media Store . Video ] Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġ[ Media Store . Audio ] Ġas Ġwell . ĠWh atever Ġ` Media . EXTERNAL _ CONTENT _ URI ` Ġyou ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġquery Ġto Ġget Ġthe Ġitems Ġis Ġthe Ġbase , Ġand Ġthe ĠID Ġis Ġthe Ġdocument Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġrequest Ġthere . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Uri Ġ= ĠContent U ris . with App ended Id ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Store . Images . Media . EXTERNAL _ CONTENT _ URI , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġid ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage Ġ= ĠMedia Store Image ( id , ĠdisplayName , Ġdate Modified , Ġcontent Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimages Ġ+= Ġimage ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġdebugging , Ġwe 'll Ġoutput Ġthe Ġimage Ġobjects Ġwe Ġcreate Ġto Ġlog cat . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . v ( TAG , Ġ" Added Ġimage : Ġ$ image ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠLog . v ( TAG , Ġ" Found Ġ${ images . size } Ġimages ") ĊĠĠĠĠĠĠĠ Ġreturn Ġimages ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHas Ġthe Ġ[ Media Store ] Ġdelete Ġthe Ġimage Ġassociated Ġwith Ġour Ġ[ Media Store Image ] Ġparameter Ġ[ image ]. ĊĠĠĠĠ Ġ* ĠWe Ġuse Ġthe Ġ[ Coroutine Context ] Ġof Ġ[ Dispatch ers . IO ] Ġto Ġcall Ġa Ġsus pending Ġblock Ġwhich Ġconsists ĊĠĠĠĠ Ġ* Ġof Ġa Ġ` try ` Ġblock Ġintended Ġto Ġcatch Ġand Ġdeal Ġwith Ġ[ Security Exception ] Ġand Ġin Ġthe Ġ` try ` Ġblock ĊĠĠĠĠ Ġ* Ġwe Ġuse Ġa Ġ[ Content Resolver ] Ġinstance Ġfor Ġour Ġapplication 's Ġpackage Ġto Ġdelete Ġthe Ġrow Ġwhose ĠURL ĊĠĠĠĠ Ġ* Ġis Ġthe Ġ[ Media Store Image . content Uri ] Ġproperty Ġof Ġour Ġ[ image ] Ġparameter , Ġfiltering Ġfor Ġrows Ġwhere ĊĠĠĠĠ Ġ* Ġthe Ġ[ Media Store . Images . Media ._ ID ] Ġcolumn Ġconsists Ġof Ġthe Ġ[ String ] Ġvalue Ġof Ġthe Ġ[ Media Store Image . id ] ĊĠĠĠĠ Ġ* Ġproperty Ġof Ġ[ image ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġwe Ġ` catch ` Ġ[ Security Exception ] Ġwe Ġcheck Ġif Ġ[ Build . VERSION . SDK _ INT ] Ġ( SDK Ġversion Ġof Ġthe ĊĠĠĠĠ Ġ* Ġsoftware Ġcurrently Ġrunning Ġon Ġthis Ġhardware Ġdevice ) Ġis Ġgreater Ġthan Ġor Ġequal Ġto ĊĠĠĠĠ Ġ* Ġ[ Build . VERSION _ CODES . Q ] Ġand Ġif Ġso Ġwe Ġinitialize Ġour Ġ[ Recover able Security Exception ] Ġvariable ĊĠĠĠĠ Ġ* Ġ` val Ġrecover able Security Exception ` Ġby Ġcasting Ġthe Ġ[ Security Exception ] Ġif Ġpossible Ġ( re throw ing ĊĠĠĠĠ Ġ* Ġthe Ġ[ Security Exception ] Ġif Ġit Ġis Ġnot ). ĠWe Ġthen Ġset Ġour Ġ[ pending Delete Image ] Ġfield Ġto Ġour ĊĠĠĠĠ Ġ* Ġparameter Ġ[ image ], Ġand Ġpost Ġa Ġtask Ġto Ġthe Ġmain Ġthread Ġto Ġset Ġour Ġ[ Intent Sender ] Ġfield ĊĠĠĠĠ Ġ* Ġ[_ permission Needed For Delete ] Ġto Ġa Ġ[ Intent Sender ] Ġthat Ġwraps Ġthe Ġsender Ġof Ġthe Ġaction ĊĠĠĠĠ Ġ* Ġ[ Pending Intent ] Ġof Ġthe Ġprimary Ġaction Ġthat Ġwill Ġinitiate Ġrecovery Ġfrom Ġthe ĊĠĠĠĠ Ġ* Ġ[ Recover able Security Exception ] Ġcontained Ġin Ġ` recover able Security Exception `. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġon Ġthe Ġother Ġhand Ġ[ Build . VERSION . SDK _ INT ] Ġis Ġless Ġthan Ġ[ Build . VERSION _ CODES . Q ] Ġwe Ġjust ĊĠĠĠĠ Ġ* Ġre throw Ġthe Ġ[ Security Exception ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġimage Ġthe Ġ[ Media Store Image ] Ġcontaining Ġthe Ġinformation Ġneeded Ġto Ġdelete Ġthe Ġimage ĊĠĠĠĠ Ġ* Ġassociated Ġwith Ġit Ġfrom Ġthe Ġfile Ġsystem . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġperform Delete Image ( image : ĠMedia Store Image ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIn Ġ[ Build . VERSION _ CODES . Q ] Ġand Ġabove , Ġit Ġisn 't Ġpossible Ġto Ġmodify ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġor Ġdelete Ġitems Ġin ĠMedia Store Ġdirectly , Ġand Ġexplicit Ġpermission ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġmust Ġusually Ġbe Ġobtained Ġto Ġdo Ġthis . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġway Ġit Ġworks Ġis Ġthe ĠOS Ġwill Ġthrow Ġa Ġ[ Recover able Security Exception ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġwhich Ġwe Ġcan Ġcatch Ġhere . ĠIn side Ġthere 's Ġan Ġ[ Intent Sender ] Ġwhich Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġactivity Ġcan Ġuse Ġto Ġprompt Ġthe Ġuser Ġto Ġgrant Ġpermission Ġto Ġthe Ġitem ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġso Ġit Ġcan Ġbe Ġeither Ġupdated Ġor Ġdeleted . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Application < Application >(). content Resolver . delete ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage . content Uri , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ Media Store . Images . Media ._ ID } Ġ= Ġ?", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( image . id . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( security Exception : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . Q ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecover able Security Exception Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsecurity Exception Ġas ? ĠRe cover able Security Exception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow Ġsecurity Exception ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSignal Ġto Ġthe ĠActivity Ġthat Ġit Ġneeds Ġto Ġrequest Ġpermission Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtry Ġthe Ġdelete Ġagain Ġif Ġit Ġsucceeds . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpending Delete Image Ġ= Ġimage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ permission Needed For Delete . post Value ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrecover able Security Exception . user Action . action Intent . intent Sender ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġsecurity Exception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConvenience Ġmethod Ġto Ġconvert Ġa Ġday / month / year Ġdate Ġinto Ġa ĠUNIX Ġtimestamp . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠWe 're Ġsuppress ing Ġthe Ġlint Ġwarning Ġbecause Ġwe 're Ġnot Ġactually Ġusing Ġthe Ġdate Ġformatter ĊĠĠĠĠ Ġ* Ġto Ġformat Ġthe Ġdate Ġto Ġdisplay , Ġjust Ġto Ġspecify Ġa Ġformat Ġto Ġuse Ġto Ġparse Ġit , Ġand Ġso Ġthe ĊĠĠĠĠ Ġ* Ġlocale Ġwarning Ġdoesn 't Ġapply . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġday Ġthe Ġday Ġof Ġthe Ġmonth Ġ( 1 - 3 1 ) ĊĠĠĠĠ Ġ* Ġ@ param Ġmonth Ġthe Ġmonth Ġ( 1 - 1 2 ) ĊĠĠĠĠ Ġ* Ġ@ param Ġyear Ġthe Ġyear ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġnumber Ġof Ġmilliseconds Ġsince ĠJanuary Ġ 1 , Ġ 1 9 7 0 , Ġ 0 0 : 0 0 : 0 0 ĠGMT Ġfor Ġthe Ġdate Ġspecified ĊĠĠĠĠ Ġ* Ġby Ġour Ġparameters . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suppress (" Same Parameter Value ") ĊĠĠĠ Ġ@ Suppress Lint (" SimpleDateFormat ") ĊĠĠĠ Ġprivate Ġfun Ġdate To Timestamp ( day : ĠInt , Ġmonth : ĠInt , Ġyear : ĠInt ): ĠLong Ġ= ĊĠĠĠĠĠĠĠ ĠSimpleDateFormat (" dd . MM . yyyy "). let Ġ{ Ġformatter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTimeUnit . MICRO SECONDS . to Seconds ( formatter . parse ("$ day .$ month .$ year ") ?. time Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSince Ġwe Ġregister Ġa Ġ[ Content Observer ], Ġwe Ġwant Ġto Ġunregister Ġthis Ġwhen Ġthe Ġ` ViewModel ` ĊĠĠĠĠ Ġ* Ġis Ġbeing Ġreleased . ĠIf Ġour Ġ[ Content Observer ] Ġfield Ġ[ content Observer ] Ġis Ġnot Ġ` null ` Ġwe Ġuse ĊĠĠĠĠ Ġ* Ġthe Ġ[ let ] Ġextension Ġfunction Ġto Ġcall Ġthe Ġ[ Content Resolver . unregister Content Observer ] Ġmethod ĊĠĠĠĠ Ġ* Ġof Ġa Ġ[ Content Resolver ] Ġinstance Ġfor Ġour Ġapplication 's Ġpackage Ġwith Ġ` it ` Ġas Ġthe Ġargument . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon Cle ared () Ġ{ ĊĠĠĠĠĠĠĠ Ġcontent Observer ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Application < Application >(). content Resolver . unregister Content Observer ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠConvenience Ġextension Ġmethod Ġto Ġregister Ġa Ġ[ Content Observer ] Ġgiven Ġa Ġlambda . ĠWe Ġinitialize Ġour Ċ Ġ* Ġ[ Content Observer ] Ġvariable Ġ` val Ġcontent Observer ` Ġto Ġa Ġnew Ġinstance Ġwhich Ġuses Ġa Ġ[ Handler ] Ġwhich Ċ Ġ* Ġuses Ġthe Ġapplication 's Ġmain Ġ[ Looper ] Ġto Ġrun Ġits Ġ[ Content Observer . onChange ] Ġmethod Ġon . ĠWe Ġoverride Ċ Ġ* Ġ[ Content Observer . onChange ] Ġto Ġcall Ġour Ġ[ observer ] Ġlambda Ġwith Ġthe Ġ[ Boolean ] Ġparameter Ġof Ġ` onChange ` Ċ Ġ* Ġ( which Ġis Ġignored Ġby Ġthe Ġlambda Ġin Ġour Ġcase ). ĠNext Ġwe Ġcall Ġthe Ġ[ Content Resolver . register Content Observer ] Ċ Ġ* Ġmethod Ġwith Ġour Ġ[ Uri ] Ġparameter Ġ[ uri ] Ġas Ġthe Ġ[ Uri ] Ġto Ġwatch Ġfor Ġchanges , Ġ` true ` Ġfor Ġits Ġ[ Boolean ] Ċ Ġ* Ġ` notify For Desc endants ` Ġparameter Ġ( when Ġ` true `, Ġthe Ġobserver Ġwill Ġalso Ġbe Ġnotified Ġwhenever Ġa Ġchange Ċ Ġ* Ġoccurs Ġto Ġthe ĠURI 's Ġdesc endants Ġin Ġthe Ġpath Ġhierarchy ), Ġand Ġ` content Observer ` Ġas Ġthe Ġobject Ġthat Ċ Ġ* Ġreceives Ġcallbacks Ġwhen Ġchanges Ġoccur . ĠFinally Ġwe Ġreturn Ġ` content Observer ` Ġto Ġthe Ġcaller . Ċ Ġ* Ċ Ġ* Ġ@ param Ġuri Ġthe Ġ[ Uri ] Ġto Ġwatch Ġfor Ġchanges . Ċ Ġ* Ġ@ param Ġobserver Ġa Ġlambda Ġwhich Ġthe Ġ[ Content Observer ] Ġshould Ġexecute Ġwhen Ġchanges Ġoccur Ġto Ġthe Ċ Ġ* Ġ[ Uri ] Ġparameter Ġ[ uri ] Ċ Ġ* Ġ@ return Ġa Ġ[ Content Observer ] Ġconfigured Ġto Ġwatch Ġthe Ġ[ Uri ] Ġparameter Ġ[ uri ] Ġfor Ġchanges Ġand Ġto Ċ Ġ* Ġexecute Ġthe Ġ[ observer ] Ġparameter Ġlambda Ġwhen Ġthey Ġoccur . Ċ Ġ*/ Ċ private Ġfun ĠContent Resolver . register Observer ( ĊĠĠĠ Ġuri : ĠUri , ĊĠĠĠ Ġobserver : Ġ( self Change : ĠBoolean ) Ġ-> ĠUnit Ċ ): ĠContent Observer Ġ{ ĊĠĠĠ Ġval Ġcontent Observer Ġ= Ġobject Ġ: ĠContent Observer ( Handler ( Looper . get Main Looper ())) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonChange ( self Change : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserver ( self Change ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġregister Content Observer ( uri , Ġtrue , Ġcontent Observer ) ĊĠĠĠ Ġreturn Ġcontent Observer Ċ } ĊĊ Ċ /** Ċ Ġ* ĠTAG Ġused Ġfor Ġlogging Ċ Ġ*/ Ċ private Ġconst Ġval ĠTAG Ġ= Ġ" MainActivity VM "