package Ġcom . simple mobile tools . contacts . helpers Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . content . Content Values Ċ import Ġandroid . content . Context Ċ import Ġandroid . database . sqlite . SQLite Database Ċ import Ġandroid . database . sqlite . SQLite Open Helper Ċ import Ġandroid . graphics . Bitmap Ċ import Ġandroid . graphics . Bitmap Factory Ċ import Ġandroid . net . Uri Ċ import Ġandroid . provider . Media Store Ċ import Ġandroid . text . TextUtils Ċ import Ġcom . google . gson . Gson Ċ import Ġcom . google . gson . reflect . Type Token Ċ import Ġcom . simple mobile tools . commons . extensions . get Blob Value Ċ import Ġcom . simple mobile tools . commons . extensions . getInt Value Ċ import Ġcom . simple mobile tools . commons . extensions . getLong Value Ċ import Ġcom . simple mobile tools . commons . extensions . getString Value Ċ import Ġcom . simple mobile tools . contacts . extensions . apply Regex Filtering Ċ import Ġcom . simple mobile tools . contacts . extensions . config Ċ import Ġcom . simple mobile tools . contacts . extensions . get ByteArray Ċ import Ġcom . simple mobile tools . contacts . extensions . get Photo Thumbnail Size Ċ import Ġcom . simple mobile tools . contacts . models .* Ċ Ċ class ĠDB Helper Ġprivate Ġconstructor ( val Ġcontext : ĠContext ) Ġ: ĠSQLite Open Helper ( context , ĠDB _ NAME , Ġnull , ĠDB _ VERSION ) Ġ{ ĊĠĠĠ Ġprivate Ġval ĠCONT ACT S _ TABLE _ NAME Ġ= Ġ" contacts " ĊĠĠĠ Ġprivate Ġval ĠCOL _ ID Ġ= Ġ" id " ĊĠĠĠ Ġprivate Ġval ĠCOL _ PREFIX Ġ= Ġ" prefix " ĊĠĠĠ Ġprivate Ġval ĠCOL _ FIRST _ NAME Ġ= Ġ" first _ name " ĊĠĠĠ Ġprivate Ġval ĠCOL _ MIDDLE _ NAME Ġ= Ġ" middle _ name " ĊĠĠĠ Ġprivate Ġval ĠCOL _ SUR NAME Ġ= Ġ" surname " ĊĠĠĠ Ġprivate Ġval ĠCOL _ SUFFIX Ġ= Ġ" suffix " ĊĠĠĠ Ġprivate Ġval ĠCOL _ N ICK NAME Ġ= Ġ" nickname " ĊĠĠĠ Ġprivate Ġval ĠCOL _ PH OTO Ġ= Ġ" photo " ĊĠĠĠ Ġprivate Ġval ĠCOL _ PHONE _ NUMBER S Ġ= Ġ" phone _ numbers " ĊĠĠĠ Ġprivate Ġval ĠCOL _ EMAIL S Ġ= Ġ" emails " ĊĠĠĠ Ġprivate Ġval ĠCOL _ EVENTS Ġ= Ġ" events " ĊĠĠĠ Ġprivate Ġval ĠCOL _ STAR RED Ġ= Ġ" star red " ĊĠĠĠ Ġprivate Ġval ĠCOL _ ADD RES SES Ġ= Ġ" addresses " ĊĠĠĠ Ġprivate Ġval ĠCOL _ IM S Ġ= Ġ" ims " ĊĠĠĠ Ġprivate Ġval ĠCOL _ NOTES Ġ= Ġ" notes " ĊĠĠĠ Ġprivate Ġval ĠCOL _ COMP ANY Ġ= Ġ" company " ĊĠĠĠ Ġprivate Ġval ĠCOL _ JOB _ POSITION Ġ= Ġ" job _ position " ĊĠĠĠ Ġprivate Ġval ĠCOL _ GROUP S Ġ= Ġ" groups " ĊĠĠĠ Ġprivate Ġval ĠCOL _ WE BS ITES Ġ= Ġ" websites " ĊĊĠĠĠ Ġprivate Ġval ĠGROUP S _ TABLE _ NAME Ġ= Ġ" groups " ĊĠĠĠ Ġprivate Ġval ĠCOL _ TITLE Ġ= Ġ" title " ĊĊĠĠĠ Ġprivate Ġval ĠFIRST _ CONTACT _ ID Ġ= Ġ 1 0 0 0 0 0 0 ĊĊĠĠĠ Ġprivate Ġval Ġm Db Ġ= Ġwritable Database ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDB _ NAME Ġ= Ġ" contacts . db " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠDB _ VERSION Ġ= Ġ 7 ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġdb Instance : ĠDB Helper ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġgson Ġ= ĠGson () ĊĊĠĠĠĠĠĠĠ Ġfun Ġnew Instance ( context : ĠContext ): ĠDB Helper Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( db Instance Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdb Instance Ġ= ĠDB Helper ( context ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdb Instance !! ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( db : ĠSQLite Database ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdb . exec SQL (" CREATE ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME Ġ($ COL _ ID ĠINTEGER ĠPRIMARY ĠKEY ĠAUTO INCREMENT , Ġ$ COL _ FIRST _ NAME ĠTEXT , Ġ$ COL _ MIDDLE _ NAME ĠTEXT , Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ COL _ SUR NAME ĠTEXT , Ġ$ COL _ PH OTO ĠBLOB , Ġ$ COL _ PHONE _ NUMBER S ĠTEXT , Ġ$ COL _ EMAIL S ĠTEXT , Ġ$ COL _ EVENTS ĠTEXT , Ġ$ COL _ STAR RED ĠINTEGER , Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ COL _ ADD RES SES ĠTEXT , Ġ$ COL _ NOTES ĠTEXT , Ġ$ COL _ GROUP S ĠTEXT , Ġ$ COL _ PREFIX ĠTEXT , Ġ$ COL _ SUFFIX ĠTEXT , Ġ$ COL _ COMP ANY ĠTEXT , Ġ$ COL _ JOB _ POSITION ĠTEXT ," Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ COL _ WE BS ITES ĠTEXT , Ġ$ COL _ N ICK NAME ĠTEXT , Ġ$ COL _ IM S ĠTEXT )") ĊĊĠĠĠĠĠĠĠ Ġ// Ġstart Ġauto increment ĠID Ġfrom ĠFIRST _ CONTACT _ ID Ġto Ġavoid Ġconflicts ĊĠĠĠĠĠĠĠ Ġdb . exec SQL (" REPLACE ĠINTO Ġsqlite _ sequence Ġ( name , Ġseq ) ĠVALUES Ġ(' $ CONTACT S _ TABLE _ NAME ', Ġ$ FIRST _ CONTACT _ ID )") ĊĊĠĠĠĠĠĠĠ Ġcreate Groups Table ( db ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Upgrade ( db : ĠSQLite Database , Ġold Version : ĠInt , Ġnew Version : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( old Version Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ ADD RES SES ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ NOTES ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( old Version Ġ< Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Groups Table ( db ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ GROUP S ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( old Version Ġ< Ġ 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ PREFIX ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ SUFFIX ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ COMP ANY ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ JOB _ POSITION ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( old Version Ġ< Ġ 5 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ WE BS ITES ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( old Version Ġ< Ġ 6 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ N ICK NAME ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( old Version Ġ< Ġ 7 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdb . exec SQL (" ALTER ĠTABLE Ġ$ CONTACT S _ TABLE _ NAME ĠADD ĠCOLUMN Ġ$ COL _ IM S ĠTEXT ĠDEFAULT Ġ'' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Groups Table ( db : ĠSQLite Database ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdb . exec SQL (" CREATE ĠTABLE Ġ$ GROUP S _ TABLE _ NAME Ġ($ COL _ ID ĠINTEGER ĠPRIMARY ĠKEY ĠAUTO INCREMENT , Ġ$ COL _ TITLE ĠTEXT )") ĊĊĠĠĠĠĠĠĠ Ġ// Ġstart Ġauto increment ĠID Ġfrom ĠFIRST _ GROUP _ ID Ġto Ġavoid Ġconflicts ĊĠĠĠĠĠĠĠ Ġdb . exec SQL (" REPLACE ĠINTO Ġsqlite _ sequence Ġ( name , Ġseq ) ĠVALUES Ġ(' $ GROUP S _ TABLE _ NAME ', Ġ$ FIRST _ GROUP _ ID )") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġinsert Contact ( contact : ĠContact ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontact Values Ġ= Ġfill Contact Values ( contact ) ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġm Db . insert ( CONTACT S _ TABLE _ NAME , Ġnull , Ġcontact Values ). toInt () ĊĠĠĠĠĠĠĠ Ġreturn Ġid Ġ!= Ġ- 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupdate Contact ( contact : ĠContact ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontact Values Ġ= Ġfill Contact Values ( contact ) ĊĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"$ COL _ ID Ġ= Ġ? " ĊĠĠĠĠĠĠĠ Ġval Ġselection Args Ġ= ĠarrayOf ( contact . id . toString ()) ĊĠĠĠĠĠĠĠ Ġreturn Ġm Db . update ( CONTACT S _ TABLE _ NAME , Ġcontact Values , Ġselection , Ġselection Args ) Ġ== Ġ 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdelete Contact ( id : ĠInt ) Ġ= Ġdelete Contacts ( array Of ( id . toString ())) ĊĊĠĠĠ Ġfun Ġdelete Contacts ( ids : ĠArray < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( ids . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġargs Ġ= ĠText Utils . join (", Ġ", Ġids ) ĊĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"$ CONTACT S _ TABLE _ NAME .$ COL _ ID ĠIN Ġ($ args )" ĊĠĠĠĠĠĠĠ Ġm Db . delete ( CONTACT S _ TABLE _ NAME , Ġselection , Ġnull ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfill Contact Values ( contact : ĠContact ): ĠContent Values Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠContent Values (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ PREFIX , Ġcontact . prefix ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ FIRST _ NAME , Ġcontact . firstName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ MIDDLE _ NAME , Ġcontact . middle Name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ SUR NAME , Ġcontact . surname ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ SUFFIX , Ġcontact . suffix ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ N ICK NAME , Ġcontact . nickname ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ PHONE _ NUMBER S , Ġgson . toJson ( contact . phone Numbers )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ EMAIL S , Ġgson . toJson ( contact . emails )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ ADD RES SES , Ġgson . toJson ( contact . addresses )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ IM S , Ġgson . toJson ( contact . IM s )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ EVENTS , Ġgson . toJson ( contact . events )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ STAR RED , Ġcontact . star red ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ NOTES , Ġcontact . notes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ GROUP S , Ġgson . toJson ( contact . groups . map Ġ{ Ġit . id Ġ})) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ COMP ANY , Ġcontact . organization . company ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ JOB _ POSITION , Ġcontact . organization . job Position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ WE BS ITES , Ġgson . toJson ( contact . websites )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( contact . photo Uri . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ PH OTO , Ġget Photo ByteArray ( contact . photo Uri )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( contact . photo Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Null ( COL _ PH OTO ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Photo ByteArray ( uri : ĠString ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġphoto Uri Ġ= ĠUri . parse ( uri ) ĊĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= ĠMedia Store . Images . Media . get Bitmap ( context . content Resolver , Ġphoto Uri ) ĊĊĠĠĠĠĠĠĠ Ġval Ġthumbnail Size Ġ= Ġcontext . get Photo Thumbnail Size () ĊĠĠĠĠĠĠĠ Ġval Ġscaled Photo Ġ= ĠBitmap . create Scaled Bitmap ( bitmap , Ġthumbnail Size Ġ* Ġ 2 , Ġthumbnail Size Ġ* Ġ 2 , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġval Ġscaled Size Photo Data Ġ= Ġscaled Photo . get ByteArray () ĊĠĠĠĠĠĠĠ Ġscaled Photo . recycle () ĊĠĠĠĠĠĠĠ Ġreturn Ġscaled Size Photo Data ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtoggle F avorites ( ids : ĠArray < String >, ĠaddTo F avorites : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontact Values Ġ= ĠContent Values () ĊĠĠĠĠĠĠĠ Ġcontact Values . put ( COL _ STAR RED , Ġif Ġ( addTo F avorites ) Ġ 1 Ġelse Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġval Ġargs Ġ= ĠText Utils . join (", Ġ", Ġids ) ĊĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"$ COL _ ID ĠIN Ġ($ args )" ĊĠĠĠĠĠĠĠ Ġm Db . update ( CONTACT S _ TABLE _ NAME , Ġcontact Values , Ġselection , Ġnull ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġinsert Group ( group : ĠGroup ): ĠGroup ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontact Values Ġ= Ġfill Group Values ( group ) ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġm Db . insert ( GROUP S _ TABLE _ NAME , Ġnull , Ġcontact Values ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( id Ġ== Ġ- 1 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠGroup ( id , Ġgroup . title ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġrename Group ( group : ĠGroup ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontact Values Ġ= Ġfill Group Values ( group ) ĊĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"$ COL _ ID Ġ= Ġ? " ĊĠĠĠĠĠĠĠ Ġval Ġselection Args Ġ= ĠarrayOf ( group . id . toString ()) ĊĠĠĠĠĠĠĠ Ġreturn Ġm Db . update ( GROUP S _ TABLE _ NAME , Ġcontact Values , Ġselection , Ġselection Args ) Ġ== Ġ 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdelete Group ( id : ĠLong ) Ġ= Ġdelete Groups ( array Of ( id . toString ())) ĊĊĠĠĠ Ġprivate Ġfun Ġdelete Groups ( ids : ĠArray < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġargs Ġ= ĠText Utils . join (", Ġ", Ġids ) ĊĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"$ GROUP S _ TABLE _ NAME .$ COL _ ID ĠIN Ġ($ args )" ĊĠĠĠĠĠĠĠ Ġm Db . delete ( GROUP S _ TABLE _ NAME , Ġselection , Ġnull ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Groups (): ĠArrayList < Group > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġgroups Ġ= ĠArrayList < Group >() ĊĠĠĠĠĠĠĠ Ġval Ġprojection Ġ= ĠarrayOf ( COL _ ID , ĠCOL _ TITLE ) ĊĠĠĠĠĠĠĠ Ġval Ġcursor Ġ= Ġm Db . query ( GROUP S _ TABLE _ NAME , Ġprojection , Ġnull , Ġnull , Ġnull , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġcursor . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( cursor . moveTo Next ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġcursor . getLong Value ( COL _ ID ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtitle Ġ= Ġcursor . getString Value ( COL _ TITLE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Ġ= ĠGroup ( id , Ġtitle ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroups . add ( group ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġgroups ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfill Group Values ( group : ĠGroup ): ĠContent Values Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠContent Values (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ TITLE , Ġgroup . title ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Contacts To Group ( contacts : ĠArrayList < Contact >, ĠgroupId : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontacts . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Group Ids Ġ= Ġit . groups . map Ġ{ Ġit . id Ġ} Ġas ĠArrayList < Long > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Group Ids . add ( groupId ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Contact Groups ( it , Ġcurrent Group Ids ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove Contacts From Group ( contacts : ĠArrayList < Contact >, ĠgroupId : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontacts . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Group Ids Ġ= Ġit . groups . map Ġ{ Ġit . id Ġ} Ġas ĠArrayList < Long > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Group Ids . remove ( groupId ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Contact Groups ( it , Ġcurrent Group Ids ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Contact Groups ( contact : ĠContact , Ġgroup Ids : ĠArrayList < Long >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontact Values Ġ= Ġfill Contact Group Values ( group Ids ) ĊĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"$ COL _ ID Ġ= Ġ? " ĊĠĠĠĠĠĠĠ Ġval Ġselection Args Ġ= ĠarrayOf ( contact . id . toString ()) ĊĠĠĠĠĠĠĠ Ġm Db . update ( CONTACT S _ TABLE _ NAME , Ġcontact Values , Ġselection , Ġselection Args ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfill Contact Group Values ( group Ids : ĠArrayList < Long >): ĠContent Values Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠContent Values (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput ( COL _ GROUP S , Ġgson . toJson ( group Ids )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Contacts ( activity : ĠActivity , Ġselection : ĠString ? Ġ= Ġnull , Ġselection Args : ĠArray < String >? Ġ= Ġnull ): ĠArrayList < Contact > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstored Groups Ġ= ĠContact s Helper ( activity ). get Stored Groups () ĊĠĠĠĠĠĠĠ Ġval Ġfilter Duplicates Ġ= Ġactivity . config . filter Duplicates ĊĠĠĠĠĠĠĠ Ġval Ġcontacts Ġ= ĠArrayList < Contact >() ĊĠĠĠĠĠĠĠ Ġval Ġprojection Ġ= ĠarrayOf ( COL _ ID , ĠCOL _ PREFIX , ĠCOL _ FIRST _ NAME , ĠCOL _ MIDDLE _ NAME , ĠCOL _ SUR NAME , ĠCOL _ SUFFIX , ĠCOL _ N ICK NAME , ĠCOL _ PHONE _ NUMBER S , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCOL _ EMAIL S , ĠCOL _ EVENTS , ĠCOL _ STAR RED , ĠCOL _ PH OTO , ĠCOL _ ADD RES SES , ĠCOL _ IM S , ĠCOL _ NOTES , ĠCOL _ GROUP S , ĠCOL _ COMP ANY , ĠCOL _ JOB _ POSITION , ĠCOL _ WE BS ITES ) ĊĊĠĠĠĠĠĠĠ Ġval Ġphone Numbers Token Ġ= Ġobject Ġ: ĠType Token < List < PhoneNumber >>() Ġ{} . type ĊĠĠĠĠĠĠĠ Ġval Ġemails Token Ġ= Ġobject Ġ: ĠType Token < List < Email >>() Ġ{} . type ĊĠĠĠĠĠĠĠ Ġval Ġaddresses Token Ġ= Ġobject Ġ: ĠType Token < List < Address >>() Ġ{} . type ĊĠĠĠĠĠĠĠ Ġval ĠI Ms Token Ġ= Ġobject Ġ: ĠType Token < List < IM >>() Ġ{} . type ĊĠĠĠĠĠĠĠ Ġval Ġevents Token Ġ= Ġobject Ġ: ĠType Token < List < Event >>() Ġ{} . type ĊĠĠĠĠĠĠĠ Ġval Ġgroup Ids Token Ġ= Ġobject Ġ: ĠType Token < List < Long >>() Ġ{} . type ĊĠĠĠĠĠĠĠ Ġval Ġwebsites Token Ġ= Ġobject Ġ: ĠType Token < List < String >>() Ġ{} . type ĊĊĠĠĠĠĠĠĠ Ġval Ġcursor Ġ= Ġm Db . query ( CONTACT S _ TABLE _ NAME , Ġprojection , Ġselection , Ġselection Args , Ġnull , Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġcursor . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( cursor . moveTo Next ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġcursor . getInt Value ( COL _ ID ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprefix Ġ= Ġcursor . getString Value ( COL _ PREFIX ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfirstName Ġ= Ġcursor . getString Value ( COL _ FIRST _ NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmiddle Name Ġ= Ġcursor . getString Value ( COL _ MIDDLE _ NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs urname Ġ= Ġcursor . getString Value ( COL _ SUR NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsuffix Ġ= Ġcursor . getString Value ( COL _ SUFFIX ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnickname Ġ= Ġcursor . getString Value ( COL _ N ICK NAME ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġphone Numbers Json Ġ= Ġcursor . getString Value ( COL _ PHONE _ NUMBER S ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġphone Numbers Ġ= Ġif Ġ( phone Numbers Json Ġ== Ġ" [] ") ĠArrayList () Ġelse Ġgson . fromJson < ArrayList < PhoneNumber >>( phone Numbers Json , Ġphone Numbers Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠArrayList ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġlabels Ġcan Ġbe Ġnull Ġat Ġupgrading Ġfrom Ġolder Ġapp Ġversions , Ġwhen Ġthe Ġlabel Ġwasn 't Ġavailable Ġat Ġall Ġyet ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġphone Numbers . filter Ġ{ Ġit . label Ġ== Ġnull Ġ}. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . label Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġemails Json Ġ= Ġcursor . getString Value ( COL _ EMAIL S ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġemails Ġ= Ġif Ġ( emails Json Ġ== Ġ" [] ") ĠArrayList () Ġelse Ġgson . fromJson < ArrayList < Email >>( emails Json , Ġemails Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠArrayList ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemails . filter Ġ{ Ġit . label Ġ== Ġnull Ġ}. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . label Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaddresses Json Ġ= Ġcursor . getString Value ( COL _ ADD RES SES ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaddresses Ġ= Ġif Ġ( addresses Json Ġ== Ġ" [] ") ĠArrayList () Ġelse Ġgson . fromJson < ArrayList < Address >>( addresses Json , Ġaddresses Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠArrayList ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaddresses . filter Ġ{ Ġit . label Ġ== Ġnull Ġ}. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . label Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠI Ms Json Ġ= Ġcursor . getString Value ( COL _ IM S ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠI Ms Ġ= Ġif Ġ( IM s Json Ġ== Ġ" [] ") ĠArrayList () Ġelse Ġgson . fromJson < ArrayList < IM >>( IM s Json , ĠI Ms Token ) Ġ?: ĠArrayList ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevents Json Ġ= Ġcursor . getString Value ( COL _ EVENTS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevents Ġ= Ġif Ġ( events Json Ġ== Ġ" [] ") ĠArrayList () Ġelse Ġgson . fromJson < ArrayList < Event >>( events Json , Ġevents Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠArrayList ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġphoto ByteArray Ġ= Ġcursor . get Blob Value ( COL _ PH OTO ) Ġ?: Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġphoto Ġ= Ġif Ġ( photo ByteArray ?. isNotEmpty () Ġ== Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBitmap Factory . decode ByteArray ( photo ByteArray , Ġ 0 , Ġphoto ByteArray . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠOut Of Memory Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnotes Ġ= Ġcursor . getString Value ( COL _ NOTES ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstar red Ġ= Ġcursor . getInt Value ( COL _ STAR RED ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Ids Json Ġ= Ġcursor . getString Value ( COL _ GROUP S ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Ids Ġ= Ġif Ġ( group Ids Json Ġ== Ġ" [] ") ĠArrayList () Ġelse Ġgson . fromJson < ArrayList < Long >>( group Ids Json , Ġgroup Ids Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠArrayList ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroups Ġ= Ġstored Groups . filter Ġ{ Ġgroup Ids . contains ( it . id ) Ġ} Ġas ĠArrayList < Group > ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcompany Ġ= Ġcursor . getString Value ( COL _ COMP ANY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjob Position Ġ= Ġcursor . getString Value ( COL _ JOB _ POSITION ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġorganization Ġ= ĠOrganization ( company , Ġjob Position ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwebsites Json Ġ= Ġcursor . getString Value ( COL _ WE BS ITES ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwebsites Ġ= Ġif Ġ( websites Json Ġ== Ġ" [] ") ĠArrayList () Ġelse Ġgson . fromJson < ArrayList < String >>( websites Json , Ġwebsites Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠArrayList ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclean Phone Numbers Ġ= ĠArrayList < PhoneNumber >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( filter Duplicates ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġphone Numbers . map To ( clean Phone Numbers ) Ġ{ ĠPhone Number ( it . value . apply Regex Filtering (), Ġ 0 , Ġ"") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontact Ġ= ĠContact ( id , Ġprefix , ĠfirstName , Ġmiddle Name , Ġs urname , Ġsuffix , Ġnickname , Ġ"", Ġphone Numbers , Ġemails , Ġaddresses , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevents , ĠS MT _ PRIVATE , Ġstar red , Ġid , Ġ"", Ġphoto , Ġnotes , Ġgroups , Ġorganization , Ġwebsites , Ġclean Phone Numbers , ĠI Ms ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontacts . add ( contact ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcontacts ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Contact With Id ( activity : ĠActivity , Ġid : ĠInt ): ĠContact ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġselection Ġ= Ġ"$ COL _ ID Ġ= Ġ? " ĊĠĠĠĠĠĠĠ Ġval Ġselection Args Ġ= ĠarrayOf ( id . toString ()) ĊĠĠĠĠĠĠĠ Ġreturn Ġget Contacts ( activity , Ġselection , Ġselection Args ). first OrNull () ĊĠĠĠ Ġ} Ċ } Ċ