package Ġnet . os mand . telegram . utils Ċ Ċ import Ġandroid . os . AsyncTask Ċ import Ġnet . os mand . GP X Utilities Ċ import Ġnet . os mand . Location Ċ import Ġnet . os mand . data . Lat Lon Ċ import Ġnet . os mand . telegram . Telegram Application Ċ import Ġnet . os mand . telegram . helpers . Location Messages Ċ import Ġnet . os mand . telegram . helpers . Location Messages . Buffer Message Ċ import Ġnet . os mand . telegram . helpers . Location Messages . Location Message Ċ import Ġnet . os mand . telegram . helpers . Show Location Helper Ċ import Ġnet . os mand . telegram . helpers . Telegram Helper Ċ import Ġnet . os mand . telegram . helpers . Telegram Ui Helper Ċ import Ġnet . os mand . util . Geo Point Parser Util Ċ import Ġnet . os mand . util . Map Utils Ċ import Ġorg . dr ink less . td . lib core . telegram . Td Api Ċ import Ġjava . io . File Ċ import Ġjava . text . SimpleDateFormat Ċ import Ġjava . util .* Ċ import Ġkotlin . math . abs Ċ Ċ const Ġval ĠTR ACK S _ DIR Ġ= Ġ" tracker /" Ċ Ċ object ĠOs mand Location Utils Ġ{ ĊĊ ĉ const Ġval ĠDEVICE _ PREFIX Ġ= Ġ" Device : Ġ" Ċ ĉ const Ġval ĠLOC ATION _ PREFIX Ġ= Ġ" Location : Ġ" Ċ ĉ const Ġval ĠLAST _ LOCATION _ PREFIX Ġ= Ġ" Last Ġlocation : Ġ" Ċ ĉ const Ġval ĠUP D ATED _ PREFIX Ġ= Ġ" Updated : Ġ" Ċ ĉ const Ġval ĠUSER _ TEXT _ LOCATION _ TITLE Ġ= Ġ"\ uD 8 3 D \ u DD FA ĠO sm And Ġsharing :" ĊĊ ĉ const Ġval ĠSH AR ING _ LINK Ġ= Ġ" https :// play . google . com / store / apps / details ? id = net . os mand . telegram " ĊĊ ĉ const Ġval ĠALT IT UDE _ PREFIX Ġ= Ġ" Alt itude : Ġ" Ċ ĉ const Ġval ĠBE AR ING _ PREFIX Ġ= Ġ" Be aring : Ġ" Ċ ĉ const Ġval ĠSPE ED _ PREFIX Ġ= Ġ" Speed : Ġ" Ċ ĉ const Ġval ĠH DO P _ PREFIX Ġ= Ġ" Horizontal Ġprecision : Ġ" Ċ ĉ const Ġval ĠBE AR ING _ SUFFIX Ġ= Ġ" Â° " ĊĊ ĉ const Ġval ĠNOW Ġ= Ġ" now " Ċ ĉ const Ġval ĠFE W _ SECONDS _ AG O Ġ= Ġ" f ew Ġseconds Ġago " Ċ ĉ const Ġval ĠSE CON DS _ AG O _ SUFFIX Ġ= Ġ" Ġseconds Ġago " Ċ ĉ const Ġval ĠMIN UTES _ AG O _ SUFFIX Ġ= Ġ" Ġminutes Ġago " Ċ ĉ const Ġval ĠHO UR S _ AG O _ SUFFIX Ġ= Ġ" Ġhours Ġago " Ċ ĉ const Ġval ĠUTC _ FORMAT _ PATTERN Ġ= Ġ" yyyy - MM - dd ĠHH : mm : ss " ĊĊ ĉ const Ġval ĠONE _ HOUR _ TIME _ MS Ġ= Ġ 6 0 Ġ* Ġ 6 0 Ġ* Ġ 1 0 0 0 Ġ// Ġ 1 Ġhour ĊĊ ĉ val ĠUTC _ DATE _ FORMAT Ġ= ĠSimpleDateFormat (" yyyy - MM - dd ", ĠLocale . US ). apply Ġ{ Ċĉ ĉ time Zone Ġ= ĠTime Zone . getTime Zone (" UTC ") Ċ ĉ } ĊĊ ĉ val ĠUTC _ TIME _ FORMAT Ġ= ĠSimpleDateFormat (" HH : mm : ss ", ĠLocale . US ). apply Ġ{ Ċĉ ĉ time Zone Ġ= ĠTime Zone . getTime Zone (" UTC ") Ċ ĉ } ĊĊ ĉ fun ĠgetLast Updated Time ( message : ĠT d Api . Message ): ĠInt Ġ{ Ċĉ ĉ val Ġcontent Ġ= Ġmessage . content Ċĉ ĉ return Ġwhen Ġ( content ) Ġ{ Ċĉĉ ĉ is ĠMessage O sm And Bot Location Ġ-> Ġcontent . last Updated Ċĉĉ ĉ is ĠMessage User Location Ġ-> Ġcontent . last Updated Ċĉĉ ĉ else Ġ-> ĠMath . max ( message . edit Date , Ġmessage . date ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġget O sm And Bot Device Name ( message : ĠT d Api . Message ): ĠString Ġ{ Ċĉ ĉ var Ġdevice Name Ġ= Ġ"" Ċĉ ĉ if Ġ( message . reply Markup Ġis ĠT d Api . Reply Markup Inline Keyboard ) Ġ{ Ċĉĉ ĉ val Ġreply Markup Ġ= Ġmessage . reply Markup Ġas ĠT d Api . Reply Markup Inline Keyboard Ċĉĉ ĉ try Ġ{ Ċĉĉĉ ĉ val Ġcontent Ġ= Ġmessage . content Ċĉĉĉ ĉ when Ġ{ Ċĉĉĉĉ ĉ content Ġis ĠT d Api . Message Text Ġ-> Ġdevice Name Ġ= Ġcontent . text . text . lines (). first OrNull ()?. remove Prefix ( DEVICE _ PREFIX ) Ġ?: Ġ"" Ċĉĉĉĉ ĉ content Ġis ĠT d Api . Message Location Ġ&& Ġreply Markup . rows [ 0 ]. size Ġ> Ġ 1 Ġ-> Ġdevice Name Ġ= Ġreply Markup . rows [ 0 ][ 0 ]. text . split ("\\ s ". to Regex ())[ 1 ] Ċĉĉĉĉ ĉ content Ġis ĠMessage O sm And Bot Location Ġ-> Ġdevice Name Ġ= Ġcontent . device Name Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ ĊĊĉĉ ĉ } Ċĉ ĉ } Ċĉ ĉ return Ġdevice Name Ċ ĉ } ĊĊ ĉ fun Ġparse Map Location ( message : ĠT d Api . Message , Ġbot Location : ĠBoolean ): ĠMessage Location Ġ{ Ċĉ ĉ val Ġres Ġ= Ġif Ġ( bot Location ) ĠMessage O sm And Bot Location () Ġelse ĠMessage User Location () Ċĉ ĉ val Ġmessage Location Ġ= Ġmessage . content Ġas ĠT d Api . Message Location Ċĉ ĉ res . apply Ġ{ Ċĉĉ ĉ lat Ġ= Ġmessage Location . location . latitude Ċĉĉ ĉ lon Ġ= Ġmessage Location . location . longitude Ċĉĉ ĉ last Updated Ġ= ĠgetLast Updated Time ( message ) Ċĉĉ ĉ type Ġ= ĠLocation Messages . TYPE _ MAP Ċĉ ĉ } Ċĉ ĉ if Ġ( res Ġis ĠMessage O sm And Bot Location ) Ġ{ Ċĉĉ ĉ res . device Name Ġ= Ġget O sm And Bot Device Name ( message ) Ċĉ ĉ } ĊĊĉ ĉ return Ġres Ċ ĉ } ĊĊ ĉ fun Ġget Sender MessageId ( message : ĠT d Api . Message ): ĠInt Ġ{ Ċĉ ĉ val Ġforward Info Ġ= Ġmessage . forward Info Ċĉ ĉ return Ġif Ġ( forward Info Ġ!= Ġnull Ġ&& Ġforward Info . origin Ġis ĠT d Api . Message Forward Origin User ) Ġ{ Ċĉĉ ĉ ( forward Info . origin Ġas ĠT d Api . Message Forward Origin User ). sender UserId Ċĉ ĉ } Ġelse Ġ{ Ċĉĉ ĉ val Ġsender Ġ= Ġmessage . sender Ċĉĉ ĉ if Ġ( sender Ġis ĠT d Api . Message Sender User ) Ġ{ Ċĉĉĉ ĉ sender . userId Ċĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉ 0 Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġparse Message ( message : ĠT d Api . Message , Ġhelper : ĠTelegram Helper , Ġprevious Message Lat Lon : ĠLat Lon ?): ĠLocation Message ? Ġ{ Ċĉ ĉ val Ġparsed Content Ġ= Ġparse Message Content ( message , Ġhelper ) Ċĉ ĉ return Ġcreate Location Message ( message , Ġparsed Content , Ġprevious Message Lat Lon ) Ċ ĉ } ĊĊ ĉ fun Ġparse Message Content ( message : ĠT d Api . Message , Ġhelper : ĠTelegram Helper ): ĠMessage Location ? Ġ{ Ċĉ ĉ val Ġsender UserId Ġ= Ġget Sender MessageId ( message ) Ċĉ ĉ val Ġfrom Bot Ġ= Ġhelper . is O sm And Bot ( sender UserId ) Ċĉ ĉ val Ġvia Bot Ġ= Ġhelper . is O sm And Bot ( message . via Bot UserId ) Ċĉ ĉ return Ġwhen Ġ( message . content ) Ġ{ Ċĉĉ ĉ is ĠT d Api . Message Text Ġ-> Ġparse Text Location (( message . content Ġas ĠT d Api . Message Text ). text , Ġ( from Bot Ġ|| Ġvia Bot )) Ċĉĉ ĉ is ĠT d Api . Message Location Ġ-> Ġparse Map Location ( message , Ġ( from Bot Ġ|| Ġvia Bot )) Ċĉĉ ĉ is ĠMessage Location Ġ-> Ġmessage . content Ġas ĠMessage Location Ċĉĉ ĉ else Ġ-> Ġnull Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġcreate Location Message ( message : ĠT d Api . Message , Ġcontent : Message Location ?, Ġprevious Message Lat Lon : ĠLat Lon ?): Location Message ? { Ċĉ ĉ if Ġ( content Ġ== Ġnull ) Ġ{ Ċĉĉ ĉ return Ġnull Ċĉ ĉ } Ċĉ ĉ val Ġsender UserId Ġ= Ġget Sender MessageId ( message ) Ċĉ ĉ val Ġmessage Type Ġ= Ġget MessageType ( message ) Ċĉ ĉ val Ġdistance From Prev Ġ= Ġif Ġ( previous Message Lat Lon Ġ!= Ġnull ) ĠMap Utils . get Distance ( previous Message Lat Lon , Ġcontent . lat , Ġcontent . lon ) Ġelse Ġ 0 . 0 Ċĉ ĉ val Ġdevice Name Ġ= Ġif Ġ( content Ġis ĠMessage O sm And Bot Location ) Ġcontent . device Name Ġelse Ġ"" ĊĊĉ ĉ return ĠLocation Message ( sender UserId , Ġmessage . chat Id , Ġcontent . lat , Ġcontent . lon , Ċĉĉ ĉ content . altitude , Ġcontent . speed , Ġcontent . hd op , Ġcontent . be aring , Ċĉĉ ĉ content . last Updated Ġ* Ġ 1 0 0 0 L , Ġmessage Type , Ġmessage . id , Ġdistance From Prev , Ġdevice Name Ċĉ ĉ ) Ċ ĉ } ĊĊ ĉ fun Ġget MessageType ( message : ĠT d Api . Message ): ĠInt Ġ{ Ċĉ ĉ val Ġold Content Ġ= Ġmessage . content Ċĉ ĉ return Ġwhen Ġ( old Content ) Ġ{ Ċĉĉ ĉ is ĠT d Api . Message Text Ġ-> ĠLocation Messages . TYPE _ TEXT Ċĉĉ ĉ is ĠT d Api . Message Location Ġ-> ĠLocation Messages . TYPE _ MAP Ċĉĉ ĉ is ĠMessage Location Ġ-> Ġold Content . type Ċĉĉ ĉ else Ġ-> Ġ- 1 Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġformat Location ( sig : ĠLocation ): ĠString Ġ{ Ċĉ ĉ return ĠString . format ( Locale . US , Ġ"% . 5 f , Ġ%. 5 f ", Ġsig . latitude , Ġsig . longitude ) Ċ ĉ } ĊĊ ĉ fun Ġformat Location ( sig : ĠLocation Message ): ĠString Ġ{ Ċĉ ĉ return ĠString . format ( Locale . US , Ġ"% . 5 f , Ġ%. 5 f ", Ġsig . lat , Ġsig . lon ) Ċ ĉ } ĊĊ ĉ fun Ġformat Location ( sig : ĠBuffer Message ): ĠString Ġ{ Ċĉ ĉ return ĠString . format ( Locale . US , Ġ"% . 5 f , Ġ%. 5 f ", Ġsig . lat , Ġsig . lon ) Ċ ĉ } ĊĊ ĉ fun Ġformat Full Time ( ti : ĠLong , Ġapp : ĠTelegram Application ): ĠString Ġ{ Ċĉ ĉ val Ġdt Ġ= ĠDate ( ti ) Ċĉ ĉ val Ġoffset Key Ġ= Ġapp . settings . utc Offset Ċĉ ĉ val Ġut c Offset Ġ= ĠData Constants . utc Offsets [ offset Key ] Ġ?: Ġ 0 f Ċĉ ĉ val Ġsimple DateFormat Ġ= ĠSimpleDateFormat ( UTC _ FORMAT _ PATTERN , ĠLocale . US ) ĊĊĉ ĉ simple DateFormat . time Zone Ġ= ĠTime Zone . getTime Zone ( Data Constants . UTC _ FORMAT ). apply Ġ{ Ċĉĉ ĉ raw Offset Ġ= Ġ( utc Offset Ġ* ĠONE _ HOUR _ TIME _ MS ). toInt () Ċĉ ĉ } ĊĊĉ ĉ return Ġ"${ simple DateFormat . format ( dt )} Ġ$ offset Key " Ċ ĉ } ĊĊ ĉ fun Ġparse O sm And Bot Location Content ( old Content : ĠMessage O sm And Bot Location , Ġcontent : ĠT d Api . Message Content ): ĠMessage O sm And Bot Location Ġ{ Ċĉ ĉ val Ġmessage Location Ġ= Ġcontent Ġas ĠT d Api . Message Location Ċĉ ĉ return ĠMessage O sm And Bot Location (). apply Ġ{ Ċĉĉ ĉ device Name Ġ= Ġold Content . device Name Ċĉĉ ĉ lat Ġ= Ġmessage Location . location . latitude Ċĉĉ ĉ lon Ġ= Ġmessage Location . location . longitude Ċĉĉ ĉ last Updated Ġ= Ġ( System . currentTimeMillis () Ġ/ Ġ 1 0 0 0 ). toInt () Ċĉĉ ĉ type Ġ= ĠLocation Messages . TYPE _ MAP Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġparse Text Location ( text : ĠT d Api . Formatted Text , Ġbot Location : ĠBoolean ): ĠMessage Location ? Ġ{ Ċĉ ĉ if Ġ( bot Location Ġ&& Ġ! text . text . startsWith ( DEVICE _ PREFIX ) Ġ|| Ġ! bot Location Ġ&& Ġ! text . text . startsWith ( USER _ TEXT _ LOCATION _ TITLE )) Ġ{ Ċĉĉ ĉ return Ġnull Ċĉ ĉ } Ċĉ ĉ val Ġres Ġ= Ġif Ġ( bot Location ) ĠMessage O sm And Bot Location () Ġelse ĠMessage User Location () Ċĉ ĉ res . type Ġ= ĠLocation Messages . TYPE _ TEXT Ċĉ ĉ var Ġlocation NA Ġ= Ġfalse Ċĉ ĉ for Ġ( s Ġin Ġtext . text . lines ()) Ġ{ Ċĉĉ ĉ when Ġ{ Ċĉĉĉ ĉ s . startsWith ( DEVICE _ PREFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ if Ġ( res Ġis ĠMessage O sm And Bot Location ) Ġ{ Ċĉĉĉĉĉ ĉ res . device Name Ġ= Ġs . remove Prefix ( DEVICE _ PREFIX ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ s . startsWith ( LOCATION _ PREFIX ) Ġ|| Ġs . startsWith ( LAST _ LOCATION _ PREFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ var Ġloc Str : ĠString Ċĉĉĉĉ ĉ var Ġparse Ġ= Ġtrue Ċĉĉĉĉ ĉ if Ġ( s . startsWith ( LAST _ LOCATION _ PREFIX )) Ġ{ Ċĉĉĉĉĉ ĉ loc Str Ġ= Ġs . remove Prefix ( LAST _ LOCATION _ PREFIX ) Ċĉĉĉĉĉ ĉ if Ġ(! location NA ) Ġ{ Ċĉĉĉĉĉĉ ĉ parse Ġ= Ġfalse Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉ ĉ loc Str Ġ= Ġs . remove Prefix ( LOCATION _ PREFIX ) Ċĉĉĉĉĉ ĉ if Ġ( loc Str . trim () Ġ== Ġ" n / a ") Ġ{ Ċĉĉĉĉĉĉ ĉ location NA Ġ= Ġtrue Ċĉĉĉĉĉĉ ĉ parse Ġ= Ġfalse Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ if Ġ( parse ) Ġ{ Ċĉĉĉĉĉ ĉ try Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġurl Text Entity Ġ= Ċĉĉĉĉĉĉĉ ĉ text . entities . first OrNull Ġ{ Ġit . type Ġis ĠT d Api . Text EntityType Text Url Ġ} Ċĉĉĉĉĉĉ ĉ if Ġ( url Text Entity Ġ!= Ġnull Ġ&& Ġurl Text Entity . offset Ġ== Ġtext . text . indexOf ( Ċĉĉĉĉĉĉĉĉ ĉ loc Str Ċĉĉĉĉĉĉĉ ĉ ) Ċĉĉĉĉĉĉ ĉ ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ val Ġurl Ġ= Ġ( url Text Entity . type Ġas ĠT d Api . Text EntityType Text Url ). url Ċĉĉĉĉĉĉĉ ĉ val Ġpoint : ĠGeo Point Parser Util . Geo Parsed Point ? Ġ= Ċĉĉĉĉĉĉĉĉ ĉ Geo Point Parser Util . parse ( url ) Ċĉĉĉĉĉĉĉ ĉ if Ġ( point Ġ!= Ġnull ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ res . lat Ġ= Ġpoint . latitude Ċĉĉĉĉĉĉĉĉ ĉ res . lon Ġ= Ġpoint . longitude Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉĉĉ ĉ val Ġ( lat S , Ġlon S ) Ġ= Ġloc Str . split (" Ġ") Ċĉĉĉĉĉĉĉ ĉ res . lat Ġ= Ġlat S . drop Last ( 1 ). toDouble () Ċĉĉĉĉĉĉĉ ĉ res . lon Ġ= Ġlon S . toDouble () ĊĊĉĉĉĉĉĉĉ ĉ val Ġtime Index Ġ= Ġloc Str . indexOf (" (" ) Ċĉĉĉĉĉĉĉ ĉ if Ġ( time Index Ġ!= Ġ- 1 ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġupdated S Ġ= Ġloc Str . substring ( time Index , Ġloc Str . length ) Ċĉĉĉĉĉĉĉĉ ĉ res . last Updated Ġ= Ċĉĉĉĉĉĉĉĉĉ ĉ ( parse Time ( updated S . remove Prefix (" (" ). remove Suffix (" ) ")) Ġ/ Ġ 1 0 0 0 ). toInt () Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉĉĉĉ ĉ e . printStackTrace () Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ s . startsWith ( ALT IT UDE _ PREFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġalt Str Ġ= Ġs . remove Prefix ( ALT IT UDE _ PREFIX ) Ċĉĉĉĉ ĉ res . altitude Ġ= Ġparse Distance ( alt Str ) Ċĉĉĉ ĉ } Ċĉĉĉ ĉ s . startsWith ( SPEED _ PREFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġspeed Str Ġ= Ġs . remove Prefix ( SPEED _ PREFIX ) Ċĉĉĉĉ ĉ res . speed Ġ= Ġparse Speed ( speed Str ) Ċĉĉĉ ĉ } Ċĉĉĉ ĉ s . startsWith ( BE AR ING _ PREFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġbe aring Str Ġ= Ġs . remove Prefix ( BE AR ING _ PREFIX ) Ċĉĉĉĉ ĉ try Ġ{ Ċĉĉĉĉĉ ĉ val Ġbe aring Ġ= Ġbe aring Str . remove Suffix ( BE AR ING _ SUFFIX ) Ċĉĉĉĉĉ ĉ res . be aring Ġ= Ġbe aring . toDouble () Ċĉĉĉĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉĉĉĉ ĉ e . printStackTrace () Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ s . startsWith ( H DO P _ PREFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġhd op Str Ġ= Ġs . remove Prefix ( H DO P _ PREFIX ) Ċĉĉĉĉ ĉ res . hd op Ġ= Ġparse Distance ( hd op Str ) Ċĉĉĉ ĉ } Ċĉĉĉ ĉ s . startsWith ( UPDATED _ PREFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ if Ġ( res . last Updated Ġ== Ġ 0 ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġupdated Str Ġ= Ġs . remove Prefix ( UPDATED _ PREFIX ) Ċĉĉĉĉĉ ĉ val Ġend Index Ġ= Ġupdated Str . indexOf (" (" ) Ċĉĉĉĉĉ ĉ val Ġupdated S Ġ= Ġupdated Str . substring ( Ċĉĉĉĉĉĉĉ 0 , Ċĉĉĉĉĉĉ ĉ if Ġ( end Index Ġ!= Ġ- 1 ) Ġend Index Ġelse Ġupdated Str . length Ċĉĉĉĉĉ ĉ ) Ċĉĉĉĉĉ ĉ val Ġparsed Time Ġ= Ġ( parse Time ( updated S . trim ()) Ġ/ Ġ 1 0 0 0 ). toInt () Ċĉĉĉĉĉ ĉ val ĠcurrentTime Ġ= Ġ( System . currentTimeMillis () Ġ/ Ġ 1 0 0 0 ) Ġ- Ġ 1 Ċĉĉĉĉĉ ĉ res . last Updated Ġ= Ċĉĉĉĉĉĉ ĉ if Ġ( parsed Time Ġ< ĠcurrentTime ) Ġparsed Time Ġelse ĠcurrentTime . toInt () Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } Ċĉ ĉ return Ġres Ċ ĉ } ĊĊ ĉ fun Ġparse Time ( time S : ĠString ): ĠLong Ġ{ Ċĉ ĉ try Ġ{ Ċĉĉ ĉ when Ġ{ Ċĉĉĉ ĉ time S . endsWith ( FE W _ SECONDS _ AG O ) Ġ-> Ġreturn ĠSystem . currentTimeMillis () Ġ- Ġ 5 0 0 0 ĊĊĉĉĉ ĉ time S . endsWith ( SECONDS _ AG O _ SUFFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġloc Str Ġ= Ġtime S . remove Suffix ( SECONDS _ AG O _ SUFFIX ) Ċĉĉĉĉ ĉ return ĠSystem . currentTimeMillis () Ġ- Ġloc Str . to Long () Ġ* Ġ 1 0 0 0 Ċĉĉĉ ĉ } Ċĉĉĉ ĉ time S . endsWith ( MIN UTES _ AG O _ SUFFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġloc Str Ġ= Ġtime S . remove Suffix ( MIN UTES _ AG O _ SUFFIX ) Ċĉĉĉĉ ĉ val Ġminutes Ġ= Ġloc Str . to Long () Ċĉĉĉĉ ĉ return ĠSystem . currentTimeMillis () Ġ- Ġminutes Ġ* Ġ 6 0 Ġ* Ġ 1 0 0 0 Ċĉĉĉ ĉ } Ċĉĉĉ ĉ time S . endsWith ( HOUR S _ AG O _ SUFFIX ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġloc Str Ġ= Ġtime S . remove Suffix ( HOUR S _ AG O _ SUFFIX ) Ċĉĉĉĉ ĉ val Ġhours Ġ= Ġloc Str . to Long () Ċĉĉĉĉ ĉ return Ġ( System . currentTimeMillis () Ġ- Ġhours Ġ* Ġ 6 0 Ġ* Ġ 6 0 Ġ* Ġ 1 0 0 0 ) Ċĉĉĉ ĉ } Ċĉĉĉ ĉ time S . contains ( Data Constants . UTC _ FORMAT ) Ġ-> Ġ{ Ċĉĉĉĉ ĉ val Ġut c Index Ġ= Ġtime S . indexOf ( Data Constants . UTC _ FORMAT ) Ċĉĉĉĉ ĉ if Ġ( utc Index Ġ!= Ġ- 1 ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġloc Str Ġ= Ġtime S . substring ( 0 , Ġut c Index ) Ċĉĉĉĉĉ ĉ val Ġut c Offset Ġ= Ġtime S . substring ( utc Index ) Ċĉĉĉĉĉ ĉ val Ġut c Time Offset Ġ= ĠData Constants . utc Offsets [ utc Offset ] Ġ?: Ġ 0 f Ċĉĉĉĉĉ ĉ val Ġsimple DateFormat Ġ= ĠSimpleDateFormat ( UTC _ FORMAT _ PATTERN , ĠLocale . US ) Ċĉĉĉĉĉ ĉ simple DateFormat . time Zone Ġ= ĠTime Zone . getTime Zone ( Data Constants . UTC _ FORMAT ). apply Ġ{ Ċĉĉĉĉĉĉĉ ĉ raw Offset Ġ= Ġ( utc Time Offset Ġ* ĠONE _ HOUR _ TIME _ MS ). toInt () Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ val Ġres Ġ= Ġsimple DateFormat . parse ( loc Str ) Ċĉĉĉĉĉ ĉ return Ġres . time Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉ ĉ e . printStackTrace () Ċĉ ĉ } Ċĉ ĉ return Ġ 0 Ċ ĉ } ĊĊ ĉ fun Ġparse Speed ( speed S : ĠString ): ĠDouble Ġ{ Ċĉ ĉ try Ġ{ Ċĉĉ ĉ if Ġ(! speed S . contains (" Ġ")) Ġ{ Ċĉĉĉ ĉ return Ġ 0 . 0 Ċĉĉ ĉ } Ċĉĉ ĉ val Ġspeed Split Ġ= Ġspeed S . split (" Ġ") Ċĉĉ ĉ val Ġspeed Val Ġ= Ġspeed Split . first (). toDouble () Ċĉĉ ĉ val Ġspeed Format Ġ= ĠOs mand Formatter . Speed Constants . values (). first OrNull Ġ{ Ġit . getDefault String () Ġ== Ġspeed Split . last () Ġ} Ċĉĉ ĉ return Ġwhen Ġ( speed Format ) Ġ{ Ċĉĉĉ ĉ Os mand Formatter . Speed Constants . KI LO METER S _ PER _ HOUR Ġ-> Ġspeed Val Ġ/ Ġ 3 . 6 f Ċĉĉĉ ĉ Os mand Formatter . Speed Constants . M ILE S _ PER _ HOUR Ġ-> Ġ( speed Val Ġ/ Ġ 3 . 6 f ) Ġ/ Ġ( Os mand Formatter . METER S _ IN _ KI LO METER Ġ/ ĠOs mand Formatter . METER S _ IN _ ONE _ M ILE ) Ċĉĉĉ ĉ Os mand Formatter . Speed Constants . NA UT ICAL M ILE S _ PER _ HOUR Ġ-> Ġ( speed Val Ġ/ Ġ 3 . 6 f ) Ġ/ Ġ( Os mand Formatter . METER S _ IN _ KI LO METER Ġ/ ĠOs mand Formatter . METER S _ IN _ ONE _ NA UT ICAL M ILE ) Ċĉĉĉ ĉ Os mand Formatter . Speed Constants . MIN UTES _ PER _ KI LO METER Ġ-> Ġ( Os mand Formatter . METER S _ IN _ KI LO METER Ġ/ Ġspeed Val ) Ġ/ Ġ 6 0 Ċĉĉĉ ĉ Os mand Formatter . Speed Constants . MIN UTES _ PER _ M ILE Ġ-> Ġ( Os mand Formatter . METER S _ IN _ ONE _ M ILE Ġ/ Ġspeed Val ) Ġ/ Ġ 6 0 Ċĉĉĉ ĉ else Ġ-> Ġspeed Val Ċĉĉ ĉ } Ċĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉ ĉ e . printStackTrace () Ċĉ ĉ } Ċĉ ĉ return Ġ 0 . 0 Ċ ĉ } ĊĊ ĉ fun Ġparse Distance ( distance S : ĠString ): ĠDouble Ġ{ Ċĉ ĉ try Ġ{ Ċĉĉ ĉ val Ġdistance Split Ġ= Ġdistance S . split (" Ġ") Ċĉĉ ĉ val Ġdistance Val Ġ= Ġdistance Split . first (). toDouble () Ċĉĉ ĉ return Ġwhen Ġ( distance Split . last ()) Ġ{ Ċĉĉĉ ĉ Os mand Formatter . FORMAT _ METER S _ KEY Ġ-> Ġreturn Ġdistance Val Ċĉĉĉ ĉ Os mand Formatter . FORMAT _ FE ET _ KEY Ġ-> Ġreturn Ġdistance Val Ġ/ ĠOs mand Formatter . FE ET _ IN _ ONE _ METER Ċĉĉĉ ĉ Os mand Formatter . FORMAT _ Y AR DS _ KEY Ġ-> Ġreturn Ġdistance Val Ġ/ ĠOs mand Formatter . Y AR DS _ IN _ ONE _ METER Ċĉĉĉ ĉ Os mand Formatter . FORMAT _ KI LO METER S _ KEY Ġ-> Ġreturn Ġdistance Val Ġ* ĠOs mand Formatter . METER S _ IN _ KI LO METER Ċĉĉĉ ĉ Os mand Formatter . FORMAT _ NA UT ICAL M ILE S _ KEY Ġ-> Ġreturn Ġdistance Val Ġ* ĠOs mand Formatter . METER S _ IN _ ONE _ NA UT ICAL M ILE Ċĉĉĉ ĉ Os mand Formatter . FORMAT _ M ILE S _ KEY Ġ-> Ġreturn Ġdistance Val Ġ* ĠOs mand Formatter . METER S _ IN _ ONE _ M ILE Ċĉĉĉ ĉ else Ġ-> Ġdistance Val Ċĉĉ ĉ } Ċĉ ĉ } Ġcatch Ġ( e : ĠException ) Ġ{ Ċĉĉ ĉ e . printStackTrace () Ċĉ ĉ } Ċĉ ĉ return Ġ 0 . 0 Ċ ĉ } ĊĊ ĉ fun ĠgetText Message Content ( update Id : ĠInt , Ġlocation : ĠBuffer Message , Ġapp : ĠTelegram Application ): ĠT d Api . Input Message Text Ġ{ Ċĉ ĉ val Ġentities Ġ= Ġmutable ListOf < Td Api . Text Entity >() Ċĉ ĉ val Ġbuilder Ġ= ĠStringBuilder () Ċĉ ĉ val Ġlocation Message Ġ= Ġformat Location ( location ) ĊĊĉ ĉ val Ġfirst Space Ġ= ĠUSER _ TEXT _ LOCATION _ TITLE . indexOf (' Ġ') Ċĉ ĉ val Ġsecond Space Ġ= ĠUSER _ TEXT _ LOCATION _ TITLE . indexOf (' Ġ', Ġfirst Space Ġ+ Ġ 1 ) Ċĉ ĉ entities . add ( Td Api . Text Entity ( builder . length Ġ+ Ġfirst Space Ġ+ Ġ 1 , Ġsecond Space Ġ- Ġfirst Space , ĠT d Api . Text EntityType Text Url ( SH AR ING _ LINK ))) Ċĉ ĉ builder . append ("$ USER _ TEXT _ LOCATION _ TITLE \ n ") ĊĊĉ ĉ entities . add ( Td Api . Text Entity ( builder . last Index , ĠLOC ATION _ PREFIX . length , ĠT d Api . Text EntityType Bold ())) Ċĉ ĉ builder . append ( LOCATION _ PREFIX ) ĊĊĉ ĉ entities . add ( Td Api . Text Entity ( builder . length , Ġlocation Message . length , Ċĉĉ ĉ Td Api . Text EntityType Text Url ("$ BASE _ SH AR ING _ URL ? lat =${ location . lat }& lon =${ location . lon } "))) Ċĉ ĉ builder . append ("$ location Message \ n ") ĊĊĉ ĉ if Ġ( location . altitude Ġ!= Ġ 0 . 0 ) Ġ{ Ċĉĉ ĉ entities . add ( Td Api . Text Entity ( builder . last Index , ĠALT IT UDE _ PREFIX . length , ĠT d Api . Text EntityType Bold ())) Ċĉĉ ĉ val Ġformatted Alt itude Ġ= ĠOs mand Formatter . get Formatted Alt ( location . altitude , Ġapp , Ġfalse ) Ċĉĉ ĉ builder . append ( String . format ( Locale . US , Ġ"$ ALT IT UDE _ PREFIX % s \ n ", Ġformatted Alt itude )) Ċĉ ĉ } Ċĉ ĉ if Ġ( location . speed Ġ> Ġ 0 ) Ġ{ Ċĉĉ ĉ entities . add ( Td Api . Text Entity ( builder . last Index , ĠSPE ED _ PREFIX . length , ĠT d Api . Text EntityType Bold ())) Ċĉĉ ĉ val Ġformatted Speed Ġ= ĠOs mand Formatter . get Formatted Speed ( location . speed . toFloat (), Ġapp , Ġfalse ) Ċĉĉ ĉ builder . append ( String . format ( Locale . US , Ġ"$ SPEED _ PREFIX % s \ n ", Ġformatted Speed )) Ċĉ ĉ } Ċĉ ĉ if Ġ( location . be aring Ġ> Ġ 0 ) Ġ{ Ċĉĉ ĉ entities . add ( Td Api . Text Entity ( builder . last Index , ĠBE AR ING _ PREFIX . length , ĠT d Api . Text EntityType Bold ())) Ċĉĉ ĉ builder . append ( String . format ( Locale . US , Ġ"$ BE AR ING _ PREFIX %. 1 f $ BE AR ING _ SUFFIX \ n ", Ġlocation . be aring )) Ċĉ ĉ } Ċĉ ĉ if Ġ( location . hd op Ġ!= Ġ 0 . 0 Ġ&& Ġlocation . speed Ġ== Ġ 0 . 0 ) Ġ{ Ċĉĉ ĉ entities . add ( Td Api . Text Entity ( builder . last Index , ĠH DO P _ PREFIX . length , ĠT d Api . Text EntityType Bold ())) Ċĉĉ ĉ val Ġformatted Hd op Ġ= ĠOs mand Formatter . get Formatted Distance ( location . hd op . toFloat (), Ġapp , Ġfalse , Ġfalse ) Ċĉĉ ĉ builder . append ( String . format ( Locale . US , Ġ"$ H DO P _ PREFIX % s \ n ", Ġformatted Hd op )) Ċĉ ĉ } Ċĉ ĉ if Ġ( update Id Ġ== Ġ 0 ) Ġ{ Ċĉĉ ĉ builder . append ( String . format ("$ UPDATED _ PREFIX % s \ n ", Ġformat Full Time ( location . time , Ġapp ))) Ċĉ ĉ } Ġelse Ġ{ Ċĉĉ ĉ builder . append ( String . format ("$ UPDATED _ PREFIX % s Ġ(% d )\ n ", Ġformat Full Time ( location . time , Ġapp ), Ġupdate Id )) Ċĉ ĉ } Ċĉ ĉ val Ġtext Message Ġ= Ġbuilder . toString (). trim () ĊĊĉ ĉ return ĠT d Api . Input Message Text ( Td Api . Formatted Text ( text Message , Ġentities . to Typed Array ()), Ġtrue , Ġtrue ) Ċ ĉ } ĊĊ ĉ fun Ġconvert Location Messages To G px Files ( app : ĠTelegram Application , Ġitems : ĠList < Location Message >, Ġnew G px Per Chat : ĠBoolean Ġ= Ġtrue ): ĠList < GP X Utilities . GP X File > Ġ{ Ċĉ ĉ val Ġdata Tracks Ġ= ĠArrayList < GP X Utilities . GP X File >() ĊĊĉ ĉ var Ġprevious Time : ĠLong Ġ= Ġ- 1 Ċĉ ĉ var Ġprevious Chat Id : ĠLong Ġ= Ġ- 1 Ċĉ ĉ var Ġprevious UserId Ġ= Ġ- 1 Ċĉ ĉ var Ġprevious Device Name Ġ= Ġ"" Ċĉ ĉ var Ġsegment : ĠGP X Utilities . Tr k Segment ? Ġ= Ġnull Ċĉ ĉ var Ġtrack : ĠGP X Utilities . Track ? Ġ= Ġnull Ċĉ ĉ var Ġg px : ĠGP X Utilities . GP X File ? Ġ= Ġnull Ċĉ ĉ var Ġcounted Locations Ġ= Ġ 0 ĊĊĉ ĉ items . forEach Ġ{ Ċĉĉ ĉ val ĠuserId Ġ= Ġit . userId Ċĉĉ ĉ val Ġchat Id Ġ= Ġit . chat Id Ċĉĉ ĉ val Ġdevice Name Ġ= Ġit . device Name Ċĉĉ ĉ val Ġtime Ġ= Ġit . time Ċĉĉ ĉ if Ġ( previous UserId Ġ!= ĠuserId Ġ|| Ġprevious Device Name Ġ!= Ġdevice Name Ġ|| Ġ( new G px Per Chat Ġ&& Ġprevious Chat Id Ġ!= Ġchat Id )) Ġ{ Ċĉĉĉ ĉ g px Ġ= ĠGP X Utilities . GP X File ( app . packageName ). apply Ġ{ Ċĉĉĉĉ ĉ metadata Ġ= ĠGP X Utilities . Metadata (). apply Ġ{ Ċĉĉĉĉĉ ĉ name Ġ= Ġget G px FileName For UserId ( app , ĠuserId , Ġchat Id , Ġtime ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ val Ġcolor Index Ġ= Ġapp . settings . get Live Track Info ( userId , Ġchat Id , Ġdevice Name )?. color Index Ġ?: Ġ- 1 Ċĉĉĉĉ ĉ if Ġ( color Index Ġ!= Ġ- 1 ) Ġ{ Ċĉĉĉĉĉ ĉ extensions To Write [" color "] Ġ= ĠShow Location Helper . GP X _ COLORS [ color Index ] Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ previous Time Ġ= Ġ 0 Ċĉĉĉ ĉ track Ġ= Ġnull Ċĉĉĉ ĉ segment Ġ= Ġnull Ċĉĉĉ ĉ data Tracks . add ( g px !! ) Ċĉĉ ĉ } Ċĉĉ ĉ if Ġ( previous Time Ġ>= Ġtime ) Ġ{ Ċĉĉĉ ĉ return @ forEach Ċĉĉ ĉ } Ċĉĉ ĉ count ed Locations ++ Ċĉĉ ĉ val Ġpt Ġ= ĠGP X Utilities . W pt Pt () Ċĉĉ ĉ pt . lat Ġ= Ġit . lat Ċĉĉ ĉ pt . lon Ġ= Ġit . lon Ċĉĉ ĉ pt . ele Ġ= Ġit . altitude Ċĉĉ ĉ pt . speed Ġ= Ġit . speed Ċĉĉ ĉ pt . hd op Ġ= Ġit . hd op Ċĉĉ ĉ pt . time Ġ= Ġtime Ċĉĉ ĉ val Ġcurrent Interval Ġ= Ġabs ( time Ġ- Ġprevious Time ) Ċĉĉ ĉ if Ġ( track Ġ!= Ġnull ) Ġ{ Ċĉĉĉ ĉ if Ġ( current Interval Ġ< Ġ 3 0 Ġ* Ġ 6 0 Ġ* Ġ 1 0 0 0 ) Ġ{ Ċĉĉĉĉ ĉ // Ġ 3 0 Ġminute Ġ- Ġsame Ġsegment Ċĉĉĉĉ ĉ segment !!. points . add ( pt ) Ċĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉ ĉ segment Ġ= ĠGP X Utilities . Tr k Segment () Ċĉĉĉĉ ĉ segment !!. points . add ( pt ) Ċĉĉĉĉ ĉ track !!. segments . add ( segment ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉ ĉ track Ġ= ĠGP X Utilities . Track () Ċĉĉĉ ĉ segment Ġ= ĠGP X Utilities . Tr k Segment () Ċĉĉĉ ĉ track !!. segments . add ( segment ) Ċĉĉĉ ĉ segment !!. points . add ( pt ) ĊĊĉĉĉ ĉ g px !!. tracks . add ( track ) Ċĉĉ ĉ } Ċĉĉ ĉ previous Time Ġ= Ġtime Ċĉĉ ĉ previous UserId Ġ= ĠuserId Ċĉĉ ĉ previous Chat Id Ġ= Ġchat Id Ċĉĉ ĉ previous Device Name Ġ= Ġdevice Name Ċĉ ĉ } ĊĊĉ ĉ return Ġdata Tracks Ċ ĉ } ĊĊ ĉ fun Ġsave G px ( app : ĠTelegram Application , Ġg px File : ĠGP X Utilities . GP X File , Ġlistener : ĠSave G px Listener ) Ġ{ Ċĉ ĉ if Ġ(! g px File . isEmpty ) Ġ{ Ċĉĉ ĉ val Ġdir Ġ= ĠFile ( app . get External Files Dir ( null ), ĠTR ACK S _ DIR ) Ċĉĉ ĉ val Ġtask Ġ= ĠSave GP X Track ToFile Task ( listener , Ġg px File , Ġdir ) Ċĉĉ ĉ task . execute On Executor ( AsyncTask . THREAD _ POOL _ EXECUT OR ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġget G px FileName For UserId ( app : ĠTelegram Application , ĠuserId : ĠInt , Ġchat Id : ĠLong , Ġtime : ĠLong ): ĠString Ġ{ Ċĉ ĉ var ĠuserName Ġ= ĠuserId . toString () Ċĉ ĉ val Ġuser Ġ= Ġapp . telegram Helper . getUser ( userId ) Ċĉ ĉ if Ġ( user Ġ!= Ġnull ) Ġ{ Ċĉĉ ĉ userName Ġ= ĠTelegram Ui Helper . getUser Name ( user ) Ċĉ ĉ } Ċĉ ĉ val Ġchat Ġ= Ġapp . telegram Helper . get Chat ( chat Id ) Ċĉ ĉ if Ġ( chat Ġ!= Ġnull Ġ&& Ġapp . telegram Helper . is Group ( chat )) Ġ{ Ċĉĉ ĉ return Ġ"${ userName }_${ chat . title }_${ UTC _ DATE _ FORMAT . format ( Date ( time )) }" Ċĉ ĉ } Ċĉ ĉ return Ġ"${ userName }_${ UTC _ DATE _ FORMAT . format ( Date ( time )) }" Ċ ĉ } ĊĊ ĉ abstract Ġclass ĠMessage Location Ġ: ĠT d Api . Message Content () Ġ{ ĊĊĉ ĉ var Ġlat : ĠDouble Ġ= ĠDouble . NaN Ċĉĉ ĉ internal Ġset Ċĉ ĉ var Ġlon : ĠDouble Ġ= ĠDouble . NaN Ċĉĉ ĉ internal Ġset Ċĉ ĉ var Ġlast Updated : ĠInt Ġ= Ġ 0 Ċĉĉ ĉ internal Ġset Ċĉ ĉ var Ġspeed : ĠDouble Ġ= Ġ 0 . 0 Ċĉĉ ĉ internal Ġset Ċĉ ĉ var Ġalt itude : ĠDouble Ġ= Ġ 0 . 0 Ċĉĉ ĉ internal Ġset Ċĉ ĉ var Ġhd op : ĠDouble Ġ= Ġ 0 . 0 Ċĉĉ ĉ internal Ġset Ċĉ ĉ var Ġbe aring : ĠDouble Ġ= Ġ 0 . 0 Ċĉĉ ĉ internal Ġset Ċĉ ĉ var Ġtype : ĠInt Ġ= Ġ- 1 Ċĉĉ ĉ internal Ġset ĊĊĉ ĉ override Ġfun Ġget Constructor () Ġ= Ġ- 1 ĊĊĉ ĉ abstract Ġfun ĠisValid (): ĠBoolean Ċ ĉ } ĊĊ ĉ class ĠMessage O sm And Bot Location Ġ: ĠMessage Location () Ġ{ ĊĊĉ ĉ var Ġdevice Name : ĠString Ġ= Ġ"" Ċĉĉ ĉ internal Ġset ĊĊĉ ĉ override Ġfun ĠisValid () Ġ= Ġdevice Name Ġ!= Ġ"" Ġ&& Ġlat Ġ!= ĠDouble . NaN Ġ&& Ġlon Ġ!= ĠDouble . NaN Ċ ĉ } ĊĊ ĉ class ĠMessage User Location Ġ: ĠMessage Location () Ġ{ ĊĊĉ ĉ override Ġfun ĠisValid () Ġ= Ġlat Ġ!= ĠDouble . NaN Ġ&& Ġlon Ġ!= ĠDouble . NaN ĊĊ ĉ } ĊĊ ĉ private Ġclass ĠSave GP X Track ToFile Task Ġinternal Ġconstructor ( Ċĉ ĉ private Ġval Ġlistener : ĠSave G px Listener ?, Ċĉ ĉ private Ġval Ġg px File : ĠGP X Utilities . GP X File , Ċĉ ĉ private Ġval Ġdir : ĠFile Ċ ĉ ) Ġ: Ċĉ ĉ AsyncTask < Void , ĠVoid , Ġjava . lang . Exception >() Ġ{ ĊĊĉ ĉ override Ġfun Ġdo In Background ( var arg Ġparams : ĠVoid ): ĠException ? Ġ{ Ċĉĉ ĉ dir . mkdir s () Ċĉĉ ĉ if Ġ( dir . parent File . can Write ()) Ġ{ Ċĉĉĉ ĉ if Ġ( dir . exists ()) Ġ{ Ċĉĉĉĉ ĉ // Ġsave Ġfile Ċĉĉĉĉ ĉ if Ġ(! g px File . isEmpty ) Ġ{ Ċĉĉĉĉĉ ĉ val ĠfileName Ġ= Ġg px File . metadata . name Ċĉĉĉĉĉ ĉ val Ġfout Ġ= ĠFile ( dir , Ġ"$ fileName . g px ") ĊĊĉĉĉĉĉ ĉ return ĠGP X Utilities . write G px File ( f out , Ġg px File ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉĉ ĉ return Ġnull Ċĉ ĉ } ĊĊĉ ĉ override Ġfun Ġon Post Execute ( warning : ĠException ?) Ġ{ Ċĉĉ ĉ if Ġ( listener Ġ!= Ġnull ) Ġ{ Ċĉĉĉ ĉ if Ġ( warning Ġ== Ġnull ) Ġ{ Ċĉĉĉĉ ĉ listener . on Saving G px Finish ( g px File . path ) Ċĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉ ĉ listener . on Saving G px Error ( warning ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ interface ĠSave G px Listener Ġ{ ĊĊĉ ĉ fun Ġon Saving G px Finish ( path : ĠString ) ĊĊĉ ĉ fun Ġon Saving G px Error ( error : ĠException ) Ċ ĉ } Ċ }