package com.fsck.k9.mail.store; import android.app.Application; import android.content.ContentValues; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.net.Uri; import android.util.Log; import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.Preferences; import com.fsck.k9.controller.MessageRemovalListener; import com.fsck.k9.controller.MessageRetrievalListener; import com.fsck.k9.helper.Regex; import com.fsck.k9.helper.Utility; import com.fsck.k9.mail.*; import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.mail.filter.Base64OutputStream; import com.fsck.k9.mail.internet.*; import com.fsck.k9.provider.AttachmentProvider; import org.apache.commons.io.IOUtils; import java.io.*; import java.net.URI; import java.net.URLEncoder; import java.util.*; import java.util.regex.Matcher; /** *
* Implements a SQLite database backed local store for Messages. **/ public class LocalStore extends Store implements Serializable { private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0]; /** * Immutable empty {@link String} array */ private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final int DB_VERSION = 37; private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.X_DESTROYED, Flag.SEEN, Flag.FLAGGED }; private String mPath; private SQLiteDatabase mDb; private File mAttachmentsDir; private Application mApplication; private String uUid = null; private static Set
"; } else { return ""; } } private String htmlifyMessageFooter() { if (K9.messageViewFixedWidthFont()) { return ""; } else { return ""; } } public String convertEmoji2ImgForDocomo(String html) { StringReader reader = new StringReader(html); StringBuilder buff = new StringBuilder(html.length() + 512); int c = 0; try { while ((c = reader.read()) != -1) { switch (c) { // These emoji codepoints are generated by tools/make_emoji in the K-9 source tree case 0xE6F9: //docomo kissmark buff.append(""); break; case 0xE729: //docomo wink buff.append(""); break; case 0xE6D2: //docomo info02 buff.append(""); break; case 0xE753: //docomo smile buff.append(""); break; case 0xE68D: //docomo heart buff.append(""); break; case 0xE6A5: //docomo downwardleft buff.append(""); break; case 0xE6AD: //docomo pouch buff.append(""); break; case 0xE6D4: //docomo by-d buff.append(""); break; case 0xE6D7: //docomo free buff.append(""); break; case 0xE6E8: //docomo seven buff.append(""); break; case 0xE74E: //docomo snail buff.append(""); break; case 0xE658: //docomo basketball buff.append(""); break; case 0xE65A: //docomo pocketbell buff.append(""); break; case 0xE6E3: //docomo two buff.append(""); break; case 0xE74A: //docomo cake buff.append(""); break; case 0xE6D0: //docomo faxto buff.append(""); break; case 0xE661: //docomo ship buff.append(""); break; case 0xE64B: //docomo virgo buff.append(""); break; case 0xE67E: //docomo ticket buff.append(""); break; case 0xE6D6: //docomo yen buff.append(""); break; case 0xE6E0: //docomo sharp buff.append(""); break; case 0xE6FE: //docomo bomb buff.append(""); break; case 0xE6E1: //docomo mobaq buff.append(""); break; case 0xE70A: //docomo sign05 buff.append(""); break; case 0xE667: //docomo bank buff.append(""); break; case 0xE731: //docomo copyright buff.append(""); break; case 0xE678: //docomo upwardright buff.append(""); break; case 0xE694: //docomo scissors buff.append(""); break; case 0xE682: //docomo bag buff.append(""); break; case 0xE64D: //docomo scorpius buff.append(""); break; case 0xE6D9: //docomo key buff.append(""); break; case 0xE734: //docomo secret buff.append(""); break; case 0xE74F: //docomo chick buff.append(""); break; case 0xE691: //docomo eye buff.append(""); break; case 0xE70B: //docomo ok buff.append(""); break; case 0xE714: //docomo door buff.append(""); break; case 0xE64F: //docomo capricornus buff.append(""); break; case 0xE674: //docomo boutique buff.append(""); break; case 0xE726: //docomo lovely buff.append(""); break; case 0xE68F: //docomo diamond buff.append(""); break; case 0xE69B: //docomo wheelchair buff.append(""); break; case 0xE747: //docomo maple buff.append(""); break; case 0xE64C: //docomo libra buff.append(""); break; case 0xE647: //docomo taurus buff.append(""); break; case 0xE645: //docomo sprinkle buff.append(""); break; case 0xE6FC: //docomo annoy buff.append(""); break; case 0xE6E6: //docomo five buff.append(""); break; case 0xE676: //docomo karaoke buff.append(""); break; case 0xE69D: //docomo moon1 buff.append(""); break; case 0xE709: //docomo sign04 buff.append(""); break; case 0xE72A: //docomo happy02 buff.append(""); break; case 0xE669: //docomo hotel buff.append(""); break; case 0xE71B: //docomo ring buff.append(""); break; case 0xE644: //docomo mist buff.append(""); break; case 0xE73B: //docomo full buff.append(""); break; case 0xE683: //docomo book buff.append(""); break; case 0xE707: //docomo sweat02 buff.append(""); break; case 0xE716: //docomo pc buff.append(""); break; case 0xE671: //docomo bar buff.append(""); break; case 0xE72B: //docomo bearing buff.append(""); break; case 0xE65C: //docomo subway buff.append(""); break; case 0xE725: //docomo gawk buff.append(""); break; case 0xE745: //docomo apple buff.append(""); break; case 0xE65F: //docomo rvcar buff.append(""); break; case 0xE664: //docomo building buff.append(""); break; case 0xE737: //docomo danger buff.append(""); break; case 0xE702: //docomo sign01 buff.append(""); break; case 0xE6EC: //docomo heart01 buff.append(""); break; case 0xE660: //docomo bus buff.append(""); break; case 0xE72D: //docomo crying buff.append(""); break; case 0xE652: //docomo sports buff.append(""); break; case 0xE6B8: //docomo on buff.append(""); break; case 0xE73C: //docomo leftright buff.append(""); break; case 0xE6BA: //docomo clock buff.append(""); break; case 0xE6F0: //docomo happy01 buff.append(""); break; case 0xE701: //docomo sleepy buff.append(""); break; case 0xE63E: //docomo sun buff.append(""); break; case 0xE67D: //docomo event buff.append(""); break; case 0xE689: //docomo memo buff.append(""); break; case 0xE68B: //docomo game buff.append(""); break; case 0xE718: //docomo wrench buff.append(""); break; case 0xE741: //docomo clover buff.append(""); break; case 0xE693: //docomo rock buff.append(""); break; case 0xE6F6: //docomo note buff.append(""); break; case 0xE67A: //docomo music buff.append(""); break; case 0xE743: //docomo tulip buff.append(""); break; case 0xE656: //docomo soccer buff.append(""); break; case 0xE69C: //docomo newmoon buff.append(""); break; case 0xE73E: //docomo school buff.append(""); break; case 0xE750: //docomo penguin buff.append(""); break; case 0xE696: //docomo downwardright buff.append(""); break; case 0xE6CE: //docomo phoneto buff.append(""); break; case 0xE728: //docomo bleah buff.append(""); break; case 0xE662: //docomo airplane buff.append(""); break; case 0xE74C: //docomo noodle buff.append(""); break; case 0xE704: //docomo sign03 buff.append(""); break; case 0xE68E: //docomo spade buff.append(""); break; case 0xE698: //docomo foot buff.append(""); break; case 0xE712: //docomo snowboard buff.append(""); break; case 0xE684: //docomo ribbon buff.append(""); break; case 0xE6DA: //docomo enter buff.append(""); break; case 0xE6EA: //docomo nine buff.append(""); break; case 0xE722: //docomo coldsweats01 buff.append(""); break; case 0xE6F7: //docomo spa buff.append(""); break; case 0xE710: //docomo rouge buff.append(""); break; case 0xE73F: //docomo wave buff.append(""); break; case 0xE686: //docomo birthday buff.append(""); break; case 0xE721: //docomo confident buff.append(""); break; case 0xE6FF: //docomo notes buff.append(""); break; case 0xE724: //docomo pout buff.append(""); break; case 0xE6A4: //docomo xmas buff.append(""); break; case 0xE6FB: //docomo flair buff.append(""); break; case 0xE71D: //docomo bicycle buff.append(""); break; case 0xE6DC: //docomo search buff.append(""); break; case 0xE757: //docomo shock buff.append(""); break; case 0xE680: //docomo nosmoking buff.append(""); break; case 0xE66D: //docomo signaler buff.append(""); break; case 0xE66A: //docomo 24hours buff.append(""); break; case 0xE6F4: //docomo wobbly buff.append(""); break; case 0xE641: //docomo snow buff.append(""); break; case 0xE6AE: //docomo pen buff.append(""); break; case 0xE70D: //docomo appli02 buff.append(""); break; case 0xE732: //docomo tm buff.append(""); break; case 0xE755: //docomo pig buff.append(""); break; case 0xE648: //docomo gemini buff.append(""); break; case 0xE6DE: //docomo flag buff.append(""); break; case 0xE6A1: //docomo dog buff.append(""); break; case 0xE6EF: //docomo heart04 buff.append(""); break; case 0xE643: //docomo typhoon buff.append(""); break; case 0xE65B: //docomo train buff.append(""); break; case 0xE746: //docomo bud buff.append(""); break; case 0xE653: //docomo baseball buff.append(""); break; case 0xE6B2: //docomo chair buff.append(""); break; case 0xE64A: //docomo leo buff.append(""); break; case 0xE6E7: //docomo six buff.append(""); break; case 0xE6E4: //docomo three buff.append(""); break; case 0xE6DF: //docomo freedial buff.append(""); break; case 0xE744: //docomo banana buff.append(""); break; case 0xE6DB: //docomo clear buff.append(""); break; case 0xE6AC: //docomo slate buff.append(""); break; case 0xE666: //docomo hospital buff.append(""); break; case 0xE663: //docomo house buff.append(""); break; case 0xE695: //docomo paper buff.append(""); break; case 0xE67F: //docomo smoking buff.append(""); break; case 0xE65D: //docomo bullettrain buff.append(""); break; case 0xE6B1: //docomo shadow buff.append(""); break; case 0xE670: //docomo cafe buff.append(""); break; case 0xE654: //docomo golf buff.append(""); break; case 0xE708: //docomo dash buff.append(""); break; case 0xE748: //docomo cherryblossom buff.append(""); break; case 0xE6F1: //docomo angry buff.append(""); break; case 0xE736: //docomo r-mark buff.append(""); break; case 0xE6A2: //docomo cat buff.append(""); break; case 0xE6D1: //docomo info01 buff.append(""); break; case 0xE687: //docomo telephone buff.append(""); break; case 0xE68C: //docomo cd buff.append(""); break; case 0xE70E: //docomo t-shirt buff.append(""); break; case 0xE733: //docomo run buff.append(""); break; case 0xE679: //docomo carouselpony buff.append(""); break; case 0xE646: //docomo aries buff.append(""); break; case 0xE690: //docomo club buff.append(""); break; case 0xE64E: //docomo sagittarius buff.append(""); break; case 0xE6F5: //docomo up buff.append(""); break; case 0xE720: //docomo think buff.append(""); break; case 0xE6E2: //docomo one buff.append(""); break; case 0xE6D8: //docomo id buff.append(""); break; case 0xE675: //docomo hairsalon buff.append(""); break; case 0xE6B7: //docomo soon buff.append(""); break; case 0xE717: //docomo loveletter buff.append(""); break; case 0xE673: //docomo fastfood buff.append(""); break; case 0xE719: //docomo pencil buff.append(""); break; case 0xE697: //docomo upwardleft buff.append(""); break; case 0xE730: //docomo clip buff.append(""); break; case 0xE6ED: //docomo heart02 buff.append(""); break; case 0xE69A: //docomo eyeglass buff.append(""); break; case 0xE65E: //docomo car buff.append(""); break; case 0xE742: //docomo cherry buff.append(""); break; case 0xE71C: //docomo sandclock buff.append(""); break; case 0xE735: //docomo recycle buff.append(""); break; case 0xE752: //docomo delicious buff.append(""); break; case 0xE69E: //docomo moon2 buff.append(""); break; case 0xE68A: //docomo tv buff.append(""); break; case 0xE706: //docomo sweat01 buff.append(""); break; case 0xE738: //docomo ban buff.append(""); break; case 0xE672: //docomo beer buff.append(""); break; case 0xE640: //docomo rain buff.append(""); break; case 0xE69F: //docomo moon3 buff.append(""); break; case 0xE657: //docomo ski buff.append(""); break; case 0xE70C: //docomo appli01 buff.append(""); break; case 0xE6E5: //docomo four buff.append(""); break; case 0xE699: //docomo shoe buff.append(""); break; case 0xE63F: //docomo cloud buff.append(""); break; case 0xE72F: //docomo ng buff.append(""); break; case 0xE6A3: //docomo yacht buff.append(""); break; case 0xE73A: //docomo pass buff.append(""); break; case 0xE67C: //docomo drama buff.append(""); break; case 0xE727: //docomo good buff.append(""); break; case 0xE6EB: //docomo zero buff.append(""); break; case 0xE72C: //docomo catface buff.append(""); break; case 0xE6D5: //docomo d-point buff.append(""); break; case 0xE6F2: //docomo despair buff.append(""); break; case 0xE700: //docomo down buff.append(""); break; case 0xE655: //docomo tennis buff.append(""); break; case 0xE703: //docomo sign02 buff.append(""); break; case 0xE711: //docomo denim buff.append(""); break; case 0xE705: //docomo impact buff.append(""); break; case 0xE642: //docomo thunder buff.append(""); break; case 0xE66C: //docomo parking buff.append(""); break; case 0xE6F3: //docomo sad buff.append(""); break; case 0xE71E: //docomo japanesetea buff.append(""); break; case 0xE6FD: //docomo punch buff.append(""); break; case 0xE73D: //docomo updown buff.append(""); break; case 0xE66F: //docomo restaurant buff.append(""); break; case 0xE66E: //docomo toilet buff.append(""); break; case 0xE739: //docomo empty buff.append(""); break; case 0xE723: //docomo coldsweats02 buff.append(""); break; case 0xE6B9: //docomo end buff.append(""); break; case 0xE67B: //docomo art buff.append(""); break; case 0xE72E: //docomo weep buff.append(""); break; case 0xE715: //docomo dollar buff.append(""); break; case 0xE6CF: //docomo mailto buff.append(""); break; case 0xE6F8: //docomo cute buff.append(""); break; case 0xE6DD: //docomo new buff.append(""); break; case 0xE651: //docomo pisces buff.append(""); break; case 0xE756: //docomo wine buff.append(""); break; case 0xE649: //docomo cancer buff.append(""); break; case 0xE650: //docomo aquarius buff.append(""); break; case 0xE740: //docomo fuji buff.append(""); break; case 0xE681: //docomo camera buff.append(""); break; case 0xE71F: //docomo watch buff.append(""); break; case 0xE6EE: //docomo heart03 buff.append(""); break; case 0xE71A: //docomo crown buff.append(""); break; case 0xE6B3: //docomo night buff.append(""); break; case 0xE66B: //docomo gasstation buff.append(""); break; case 0xE692: //docomo ear buff.append(""); break; case 0xE685: //docomo present buff.append(""); break; case 0xE6E9: //docomo eight buff.append(""); break; case 0xE70F: //docomo moneybag buff.append(""); break; case 0xE749: //docomo riceball buff.append(""); break; case 0xE6A0: //docomo fullmoon buff.append(""); break; case 0xE74D: //docomo bread buff.append(""); break; case 0xE665: //docomo postoffice buff.append(""); break; case 0xE677: //docomo movie buff.append(""); break; case 0xE668: //docomo atm buff.append(""); break; case 0xE688: //docomo mobilephone buff.append(""); break; case 0xE6FA: //docomo shine buff.append(""); break; case 0xE713: //docomo bell buff.append(""); break; case 0xE74B: //docomo bottle buff.append(""); break; case 0xE754: //docomo horse buff.append(""); break; case 0xE751: //docomo fish buff.append(""); break; case 0xE659: //docomo motorsports buff.append(""); break; case 0xE6D3: //docomo mail buff.append(""); break; // These emoji codepoints are generated by tools/make_emoji in the K-9 source tree // The spaces between the < and the img are a hack to avoid triggering // K-9's 'load images' button case 0xE223: //softbank eight buff.append(""); break; case 0xE415: //softbank coldsweats01 buff.append(""); break; case 0xE21F: //softbank four buff.append(""); break; case 0xE125: //softbank ticket buff.append(""); break; case 0xE148: //softbank book buff.append(""); break; case 0xE242: //softbank cancer buff.append(""); break; case 0xE31C: //softbank rouge buff.append(""); break; case 0xE252: //softbank danger buff.append(""); break; case 0xE011: //softbank scissors buff.append(""); break; case 0xE342: //softbank riceball buff.append(""); break; case 0xE04B: //softbank rain buff.append(""); break; case 0xE03E: //softbank note buff.append(""); break; case 0xE43C: //softbank sprinkle buff.append(""); break; case 0xE20A: //softbank wheelchair buff.append(""); break; case 0xE42A: //softbank basketball buff.append(""); break; case 0xE03D: //softbank movie buff.append(""); break; case 0xE30E: //softbank smoking buff.append(""); break; case 0xE003: //softbank kissmark buff.append(""); break; case 0xE21C: //softbank one buff.append(""); break; case 0xE237: //softbank upwardleft buff.append(""); break; case 0xE407: //softbank sad buff.append(""); break; case 0xE03B: //softbank fuji buff.append(""); break; case 0xE40E: //softbank gawk buff.append(""); break; case 0xE245: //softbank libra buff.append(""); break; case 0xE24A: //softbank pisces buff.append(""); break; case 0xE443: //softbank typhoon buff.append(""); break; case 0xE052: //softbank dog buff.append(""); break; case 0xE244: //softbank virgo buff.append(""); break; case 0xE523: //softbank chick buff.append(""); break; case 0xE023: //softbank heart03 buff.append(""); break; case 0xE325: //softbank bell buff.append(""); break; case 0xE239: //softbank downwardleft buff.append(""); break; case 0xE20C: //softbank heart buff.append(""); break; case 0xE211: //softbank freedial buff.append(""); break; case 0xE11F: //softbank chair buff.append(""); break; case 0xE108: //softbank coldsweats02 buff.append(""); break; case 0xE330: //softbank dash buff.append(""); break; case 0xE404: //softbank smile buff.append(""); break; case 0xE304: //softbank tulip buff.append(""); break; case 0xE419: //softbank eye buff.append(""); break; case 0xE13D: //softbank thunder buff.append(""); break; case 0xE013: //softbank ski buff.append(""); break; case 0xE136: //softbank bicycle buff.append(""); break; case 0xE059: //softbank angry buff.append(""); break; case 0xE01D: //softbank airplane buff.append(""); break; case 0xE048: //softbank snow buff.append(""); break; case 0xE435: //softbank bullettrain buff.append(""); break; case 0xE20E: //softbank spade buff.append(""); break; case 0xE247: //softbank sagittarius buff.append(""); break; case 0xE157: //softbank school buff.append(""); break; case 0xE10F: //softbank flair buff.append(""); break; case 0xE502: //softbank art buff.append(""); break; case 0xE338: //softbank japanesetea buff.append(""); break; case 0xE34B: //softbank birthday buff.append(""); break; case 0xE22B: //softbank empty buff.append(""); break; case 0xE311: //softbank bomb buff.append(""); break; case 0xE012: //softbank paper buff.append(""); break; case 0xE151: //softbank toilet buff.append(""); break; case 0xE01A: //softbank horse buff.append(""); break; case 0xE03A: //softbank gasstation buff.append(""); break; case 0xE03F: //softbank key buff.append(""); break; case 0xE00D: //softbank punch buff.append(""); break; case 0xE24D: //softbank ok buff.append(""); break; case 0xE105: //softbank bleah buff.append(""); break; case 0xE00E: //softbank good buff.append(""); break; case 0xE154: //softbank atm buff.append(""); break; case 0xE405: //softbank wink buff.append(""); break; case 0xE030: //softbank cherryblossom buff.append(""); break; case 0xE057: //softbank happy01 buff.append(""); break; case 0xE229: //softbank id buff.append(""); break; case 0xE016: //softbank baseball buff.append(""); break; case 0xE044: //softbank wine buff.append(""); break; case 0xE115: //softbank run buff.append(""); break; case 0xE14F: //softbank parking buff.append(""); break; case 0xE327: //softbank heart04 buff.append(""); break; case 0xE014: //softbank golf buff.append(""); break; case 0xE021: //softbank sign01 buff.append(""); break; case 0xE30A: //softbank music buff.append(""); break; case 0xE411: //softbank crying buff.append(""); break; case 0xE536: //softbank foot buff.append(""); break; case 0xE047: //softbank beer buff.append(""); break; case 0xE43E: //softbank wave buff.append(""); break; case 0xE022: //softbank heart01 buff.append(""); break; case 0xE007: //softbank shoe buff.append(""); break; case 0xE010: //softbank rock buff.append(""); break; case 0xE32E: //softbank shine buff.append(""); break; case 0xE055: //softbank penguin buff.append(""); break; case 0xE03C: //softbank karaoke buff.append(""); break; case 0xE018: //softbank soccer buff.append(""); break; case 0xE159: //softbank bus buff.append(""); break; case 0xE107: //softbank shock buff.append(""); break; case 0xE04A: //softbank sun buff.append(""); break; case 0xE156: //softbank 24hours buff.append(""); break; case 0xE110: //softbank clover buff.append(""); break; case 0xE034: //softbank ring buff.append(""); break; case 0xE24F: //softbank r-mark buff.append(""); break; case 0xE112: //softbank present buff.append(""); break; case 0xE14D: //softbank bank buff.append(""); break; case 0xE42E: //softbank rvcar buff.append(""); break; case 0xE13E: //softbank boutique buff.append(""); break; case 0xE413: //softbank weep buff.append(""); break; case 0xE241: //softbank gemini buff.append(""); break; case 0xE212: //softbank new buff.append(""); break; case 0xE324: //softbank slate buff.append(""); break; case 0xE220: //softbank five buff.append(""); break; case 0xE503: //softbank drama buff.append(""); break; case 0xE248: //softbank capricornus buff.append(""); break; case 0xE049: //softbank cloud buff.append(""); break; case 0xE243: //softbank leo buff.append(""); break; case 0xE326: //softbank notes buff.append(""); break; case 0xE00B: //softbank faxto buff.append(""); break; case 0xE221: //softbank six buff.append(""); break; case 0xE240: //softbank taurus buff.append(""); break; case 0xE24E: //softbank copyright buff.append(""); break; case 0xE224: //softbank nine buff.append(""); break; case 0xE008: //softbank camera buff.append(""); break; case 0xE01E: //softbank train buff.append(""); break; case 0xE20D: //softbank diamond buff.append(""); break; case 0xE009: //softbank telephone buff.append(""); break; case 0xE019: //softbank fish buff.append(""); break; case 0xE01C: //softbank yacht buff.append(""); break; case 0xE40A: //softbank confident buff.append(""); break; case 0xE246: //softbank scorpius buff.append(""); break; case 0xE120: //softbank fastfood buff.append(""); break; case 0xE323: //softbank bag buff.append(""); break; case 0xE345: //softbank apple buff.append(""); break; case 0xE339: //softbank bread buff.append(""); break; case 0xE13C: //softbank sleepy buff.append(""); break; case 0xE106: //softbank lovely buff.append(""); break; case 0xE340: //softbank noodle buff.append(""); break; case 0xE20F: //softbank club buff.append(""); break; case 0xE114: //softbank search buff.append(""); break; case 0xE10E: //softbank crown buff.append(""); break; case 0xE406: //softbank wobbly buff.append(""); break; case 0xE331: //softbank sweat02 buff.append(""); break; case 0xE04F: //softbank cat buff.append(""); break; case 0xE301: //softbank memo buff.append(""); break; case 0xE01B: //softbank car buff.append(""); break; case 0xE314: //softbank ribbon buff.append(""); break; case 0xE315: //softbank secret buff.append(""); break; case 0xE236: //softbank up buff.append(""); break; case 0xE208: //softbank nosmoking buff.append(""); break; case 0xE006: //softbank t-shirt buff.append(""); break; case 0xE12A: //softbank tv buff.append(""); break; case 0xE238: //softbank downwardright buff.append(""); break; case 0xE10B: //softbank pig buff.append(""); break; case 0xE126: //softbank cd buff.append(""); break; case 0xE402: //softbank catface buff.append(""); break; case 0xE416: //softbank pout buff.append(""); break; case 0xE045: //softbank cafe buff.append(""); break; case 0xE41B: //softbank ear buff.append(""); break; case 0xE23F: //softbank aries buff.append(""); break; case 0xE21E: //softbank three buff.append(""); break; case 0xE056: //softbank delicious buff.append(""); break; case 0xE14E: //softbank signaler buff.append(""); break; case 0xE155: //softbank hospital buff.append(""); break; case 0xE033: //softbank xmas buff.append(""); break; case 0xE22A: //softbank full buff.append(""); break; case 0xE123: //softbank spa buff.append(""); break; case 0xE132: //softbank motorsports buff.append(""); break; case 0xE434: //softbank subway buff.append(""); break; case 0xE403: //softbank think buff.append(""); break; case 0xE043: //softbank restaurant buff.append(""); break; case 0xE537: //softbank tm buff.append(""); break; case 0xE058: //softbank despair buff.append(""); break; case 0xE04C: //softbank moon3 buff.append(""); break; case 0xE21D: //softbank two buff.append(""); break; case 0xE202: //softbank ship buff.append(""); break; case 0xE30B: //softbank bottle buff.append(""); break; case 0xE118: //softbank maple buff.append(""); break; case 0xE103: //softbank loveletter buff.append(""); break; case 0xE225: //softbank zero buff.append(""); break; case 0xE00C: //softbank pc buff.append(""); break; case 0xE210: //softbank sharp buff.append(""); break; case 0xE015: //softbank tennis buff.append(""); break; case 0xE038: //softbank building buff.append(""); break; case 0xE02D: //softbank clock buff.append(""); break; case 0xE334: //softbank annoy buff.append(""); break; case 0xE153: //softbank postoffice buff.append(""); break; case 0xE222: //softbank seven buff.append(""); break; case 0xE12F: //softbank dollar buff.append(""); break; case 0xE00A: //softbank mobilephone buff.append(""); break; case 0xE158: //softbank hotel buff.append(""); break; case 0xE249: //softbank aquarius buff.append(""); break; case 0xE036: //softbank house buff.append(""); break; case 0xE046: //softbank cake buff.append(""); break; case 0xE104: //softbank phoneto buff.append(""); break; case 0xE44B: //softbank night buff.append(""); break; case 0xE313: //softbank hairsalon buff.append(""); break; // These emoji codepoints are generated by tools/make_emoji in the K-9 source tree // The spaces between the < and the img are a hack to avoid triggering // K-9's 'load images' button case 0xE488: //kddi sun buff.append(""); break; case 0xEA88: //kddi id buff.append(""); break; case 0xE4BA: //kddi baseball buff.append(""); break; case 0xE525: //kddi four buff.append(""); break; case 0xE578: //kddi free buff.append(""); break; case 0xE4C1: //kddi wine buff.append(""); break; case 0xE512: //kddi bell buff.append(""); break; case 0xEB83: //kddi rock buff.append(""); break; case 0xE4D0: //kddi cake buff.append(""); break; case 0xE473: //kddi crying buff.append(""); break; case 0xE48C: //kddi rain buff.append(""); break; case 0xEAC2: //kddi bearing buff.append(""); break; case 0xE47E: //kddi nosmoking buff.append(""); break; case 0xEAC0: //kddi despair buff.append(""); break; case 0xE559: //kddi r-mark buff.append(""); break; case 0xEB2D: //kddi up buff.append(""); break; case 0xEA89: //kddi full buff.append(""); break; case 0xEAC9: //kddi gawk buff.append(""); break; case 0xEB79: //kddi recycle buff.append(""); break; case 0xE5AC: //kddi zero buff.append(""); break; case 0xEAAE: //kddi japanesetea buff.append(""); break; case 0xEB30: //kddi sign03 buff.append(""); break; case 0xE4B6: //kddi soccer buff.append(""); break; case 0xE556: //kddi downwardleft buff.append(""); break; case 0xE4BE: //kddi slate buff.append(""); break; case 0xE4A5: //kddi toilet buff.append(""); break; // Skipping kddi codepoint E523 two // It conflicts with an earlier definition from another carrier: // softbank chick case 0xE496: //kddi scorpius buff.append(""); break; case 0xE4C6: //kddi game buff.append(""); break; case 0xE5A0: //kddi birthday buff.append(""); break; case 0xE5B8: //kddi pc buff.append(""); break; case 0xE516: //kddi hairsalon buff.append(""); break; case 0xE475: //kddi sleepy buff.append(""); break; case 0xE4A3: //kddi atm buff.append(""); break; case 0xE59A: //kddi basketball buff.append(""); break; case 0xE497: //kddi sagittarius buff.append(""); break; case 0xEACD: //kddi delicious buff.append(""); break; case 0xE5A8: //kddi newmoon buff.append(""); break; case 0xE49E: //kddi ticket buff.append(""); break; case 0xE5AE: //kddi wobbly buff.append(""); break; case 0xE4E6: //kddi sweat02 buff.append(""); break; case 0xE59E: //kddi event buff.append(""); break; case 0xE4AB: //kddi house buff.append(""); break; case 0xE491: //kddi gemini buff.append(""); break; case 0xE4C9: //kddi xmas buff.append(""); break; case 0xE5BE: //kddi note buff.append(""); break; case 0xEB2F: //kddi sign02 buff.append(""); break; case 0xE508: //kddi music buff.append(""); break; case 0xE5DF: //kddi hospital buff.append(""); break; case 0xE5BC: //kddi subway buff.append(""); break; case 0xE5C9: //kddi crown buff.append(""); break; case 0xE4BC: //kddi spa buff.append(""); break; case 0xE514: //kddi ring buff.append(""); break; // Skipping kddi codepoint E502 tv // It conflicts with an earlier definition from another carrier: // softbank art case 0xE4AC: //kddi restaurant buff.append(""); break; case 0xE529: //kddi eight buff.append(""); break; case 0xE518: //kddi search buff.append(""); break; case 0xE505: //kddi notes buff.append(""); break; case 0xE498: //kddi capricornus buff.append(""); break; case 0xEB7E: //kddi snail buff.append(""); break; case 0xEA97: //kddi bottle buff.append(""); break; case 0xEB08: //kddi phoneto buff.append(""); break; case 0xE4D2: //kddi cherry buff.append(""); break; case 0xE54D: //kddi downwardright buff.append(""); break; case 0xE5C3: //kddi wink buff.append(""); break; case 0xEAAC: //kddi ski buff.append(""); break; case 0xE515: //kddi camera buff.append(""); break; case 0xE5B6: //kddi t-shirt buff.append(""); break; case 0xE5C4: //kddi lovely buff.append(""); break; case 0xE4AD: //kddi building buff.append(""); break; case 0xE4CE: //kddi maple buff.append(""); break; case 0xE5AA: //kddi moon2 buff.append(""); break; case 0xE5B4: //kddi noodle buff.append(""); break; case 0xE5A6: //kddi scissors buff.append(""); break; case 0xE4AA: //kddi bank buff.append(""); break; case 0xE4B5: //kddi train buff.append(""); break; case 0xE477: //kddi heart03 buff.append(""); break; case 0xE481: //kddi danger buff.append(""); break; case 0xE597: //kddi cafe buff.append(""); break; case 0xEB2B: //kddi shoe buff.append(""); break; case 0xEB7C: //kddi wave buff.append(""); break; case 0xE471: //kddi happy01 buff.append(""); break; case 0xE4CA: //kddi cherryblossom buff.append(""); break; case 0xE4D5: //kddi riceball buff.append(""); break; case 0xE587: //kddi wrench buff.append(""); break; case 0xEB2A: //kddi foot buff.append(""); break; case 0xE47D: //kddi smoking buff.append(""); break; case 0xE4DC: //kddi penguin buff.append(""); break; case 0xE4B3: //kddi airplane buff.append(""); break; case 0xE4DE: //kddi pig buff.append(""); break; case 0xE59B: //kddi pocketbell buff.append(""); break; case 0xE4AF: //kddi bus buff.append(""); break; case 0xE4A6: //kddi parking buff.append(""); break; case 0xE486: //kddi moon3 buff.append(""); break; case 0xE5A4: //kddi eye buff.append(""); break; case 0xE50C: //kddi cd buff.append(""); break; case 0xE54C: //kddi upwardleft buff.append(""); break; case 0xEA82: //kddi ship buff.append(""); break; case 0xE4B1: //kddi car buff.append(""); break; case 0xEB80: //kddi smile buff.append(""); break; case 0xE5B0: //kddi impact buff.append(""); break; case 0xE504: //kddi moneybag buff.append(""); break; case 0xE4B9: //kddi motorsports buff.append(""); break; case 0xE494: //kddi virgo buff.append(""); break; case 0xE595: //kddi heart01 buff.append(""); break; case 0xEB03: //kddi pen buff.append(""); break; case 0xE57D: //kddi yen buff.append(""); break; case 0xE598: //kddi mist buff.append(""); break; case 0xE5A2: //kddi diamond buff.append(""); break; case 0xE4A4: //kddi 24hours buff.append(""); break; case 0xE524: //kddi three buff.append(""); break; case 0xEB7B: //kddi updown buff.append(""); break; case 0xE5A1: //kddi spade buff.append(""); break; case 0xE495: //kddi libra buff.append(""); break; case 0xE588: //kddi mobilephone buff.append(""); break; case 0xE599: //kddi golf buff.append(""); break; case 0xE520: //kddi faxto buff.append(""); break; // Skipping kddi codepoint E503 karaoke // It conflicts with an earlier definition from another carrier: // softbank drama case 0xE4D6: //kddi fastfood buff.append(""); break; case 0xE4A1: //kddi pencil buff.append(""); break; case 0xE522: //kddi one buff.append(""); break; case 0xEB84: //kddi sharp buff.append(""); break; case 0xE476: //kddi flair buff.append(""); break; case 0xE46B: //kddi run buff.append(""); break; case 0xEAF5: //kddi drama buff.append(""); break; case 0xEAB9: //kddi apple buff.append(""); break; case 0xE4EB: //kddi kissmark buff.append(""); break; case 0xE55D: //kddi enter buff.append(""); break; case 0xE59F: //kddi ribbon buff.append(""); break; case 0xE526: //kddi five buff.append(""); break; case 0xE571: //kddi gasstation buff.append(""); break; case 0xE517: //kddi movie buff.append(""); break; case 0xE4B8: //kddi snowboard buff.append(""); break; case 0xEAE8: //kddi sprinkle buff.append(""); break; case 0xEA80: //kddi school buff.append(""); break; case 0xE47C: //kddi sandclock buff.append(""); break; case 0xEB31: //kddi sign05 buff.append(""); break; case 0xE5AB: //kddi clear buff.append(""); break; case 0xE5DE: //kddi postoffice buff.append(""); break; case 0xEB62: //kddi mailto buff.append(""); break; case 0xE528: //kddi seven buff.append(""); break; case 0xE4C2: //kddi bar buff.append(""); break; case 0xE487: //kddi thunder buff.append(""); break; case 0xE5A9: //kddi moon1 buff.append(""); break; case 0xEB7A: //kddi leftright buff.append(""); break; case 0xE513: //kddi clover buff.append(""); break; case 0xE492: //kddi cancer buff.append(""); break; case 0xEB78: //kddi loveletter buff.append(""); break; case 0xE4E0: //kddi chick buff.append(""); break; case 0xE4CF: //kddi present buff.append(""); break; case 0xE478: //kddi heart04 buff.append(""); break; case 0xEAC3: //kddi sad buff.append(""); break; case 0xE52A: //kddi nine buff.append(""); break; case 0xE482: //kddi sign01 buff.append(""); break; case 0xEABF: //kddi catface buff.append(""); break; case 0xE527: //kddi six buff.append(""); break; case 0xE52C: //kddi mobaq buff.append(""); break; case 0xE485: //kddi snow buff.append(""); break; case 0xE4B7: //kddi tennis buff.append(""); break; case 0xE5BD: //kddi fuji buff.append(""); break; case 0xE558: //kddi copyright buff.append(""); break; case 0xE4D8: //kddi horse buff.append(""); break; case 0xE4B0: //kddi bullettrain buff.append(""); break; case 0xE596: //kddi telephone buff.append(""); break; case 0xE48F: //kddi aries buff.append(""); break; case 0xE46A: //kddi signaler buff.append(""); break; case 0xE472: //kddi angry buff.append(""); break; case 0xE54E: //kddi tm buff.append(""); break; case 0xE51A: //kddi boutique buff.append(""); break; case 0xE493: //kddi leo buff.append(""); break; case 0xE5A3: //kddi club buff.append(""); break; case 0xE499: //kddi aquarius buff.append(""); break; case 0xE4AE: //kddi bicycle buff.append(""); break; case 0xE4E7: //kddi bleah buff.append(""); break; case 0xE49F: //kddi book buff.append(""); break; case 0xE5AD: //kddi ok buff.append(""); break; case 0xE5A7: //kddi paper buff.append(""); break; case 0xE4E5: //kddi annoy buff.append(""); break; case 0xE4A0: //kddi clip buff.append(""); break; case 0xE509: //kddi rouge buff.append(""); break; case 0xEAAF: //kddi bread buff.append(""); break; case 0xE519: //kddi key buff.append(""); break; case 0xE594: //kddi clock buff.append(""); break; case 0xEB7D: //kddi bud buff.append(""); break; case 0xEA8A: //kddi empty buff.append(""); break; case 0xE5B5: //kddi new buff.append(""); break; case 0xE47A: //kddi bomb buff.append(""); break; case 0xE5C6: //kddi coldsweats02 buff.append(""); break; case 0xE49A: //kddi pisces buff.append(""); break; case 0xE4F3: //kddi punch buff.append(""); break; case 0xEB5D: //kddi pout buff.append(""); break; case 0xE469: //kddi typhoon buff.append(""); break; case 0xE5B1: //kddi sweat01 buff.append(""); break; case 0xE4C7: //kddi dollar buff.append(""); break; case 0xE5C5: //kddi shock buff.append(""); break; case 0xE4F9: //kddi good buff.append(""); break; case 0xE4F1: //kddi secret buff.append(""); break; case 0xE4E4: //kddi tulip buff.append(""); break; case 0xEA81: //kddi hotel buff.append(""); break; case 0xE4FE: //kddi eyeglass buff.append(""); break; case 0xEAF1: //kddi night buff.append(""); break; case 0xE555: //kddi upwardright buff.append(""); break; case 0xEB2E: //kddi down buff.append(""); break; case 0xE4DB: //kddi cat buff.append(""); break; case 0xE59C: //kddi art buff.append(""); break; case 0xEB69: //kddi weep buff.append(""); break; case 0xE4F4: //kddi dash buff.append(""); break; case 0xE490: //kddi taurus buff.append(""); break; case 0xE57A: //kddi watch buff.append(""); break; case 0xEB2C: //kddi flag buff.append(""); break; case 0xEB77: //kddi denim buff.append(""); break; case 0xEAC5: //kddi confident buff.append(""); break; case 0xE4B4: //kddi yacht buff.append(""); break; case 0xE49C: //kddi bag buff.append(""); break; case 0xE5A5: //kddi ear buff.append(""); break; case 0xE4E1: //kddi dog buff.append(""); break; case 0xE521: //kddi mail buff.append(""); break; case 0xEB35: //kddi banana buff.append(""); break; case 0xEAA5: //kddi heart buff.append(""); break; case 0xE47F: //kddi wheelchair buff.append(""); break; case 0xEB75: //kddi heart02 buff.append(""); break; case 0xE48D: //kddi cloud buff.append(""); break; case 0xE4C3: //kddi beer buff.append(""); break; case 0xEAAB: //kddi shine buff.append(""); break; case 0xEA92: //kddi memo buff.append(""); break; default: buff.append((char)c); }//switch } } catch (IOException e) { //Should never happen Log.e(K9.LOG_TAG, null, e); } return buff.toString(); } @Override public boolean isInTopGroup() { return inTopGroup; } public void setInTopGroup(boolean inTopGroup) { this.inTopGroup = inTopGroup; } } public class LocalTextBody extends TextBody { private String mBodyForDisplay; public LocalTextBody(String body) { super(body); } public LocalTextBody(String body, String bodyForDisplay) throws MessagingException { super(body); this.mBodyForDisplay = bodyForDisplay; } public String getBodyForDisplay() { return mBodyForDisplay; } public void setBodyForDisplay(String mBodyForDisplay) { this.mBodyForDisplay = mBodyForDisplay; } }//LocalTextBody public class LocalMessage extends MimeMessage { private long mId; private int mAttachmentCount; private String mSubject; private String mPreview = ""; private boolean mHeadersLoaded = false; private boolean mMessageDirty = false; public LocalMessage() { } LocalMessage(String uid, Folder folder) throws MessagingException { this.mUid = uid; this.mFolder = folder; } private void populateFromGetMessageCursor(Cursor cursor) throws MessagingException { this.setSubject(cursor.getString(0) == null ? "" : cursor.getString(0)); Address[] from = Address.unpack(cursor.getString(1)); if (from.length > 0) { this.setFrom(from[0]); } this.setInternalSentDate(new Date(cursor.getLong(2))); this.setUid(cursor.getString(3)); String flagList = cursor.getString(4); if (flagList != null && flagList.length() > 0) { String[] flags = flagList.split(","); for (String flag : flags) { try { this.setFlagInternal(Flag.valueOf(flag), true); } catch (Exception e) { if ("X_BAD_FLAG".equals(flag) == false) { Log.w(K9.LOG_TAG, "Unable to parse flag " + flag); } } } } this.mId = cursor.getLong(5); this.setRecipients(RecipientType.TO, Address.unpack(cursor.getString(6))); this.setRecipients(RecipientType.CC, Address.unpack(cursor.getString(7))); this.setRecipients(RecipientType.BCC, Address.unpack(cursor.getString(8))); this.setReplyTo(Address.unpack(cursor.getString(9))); this.mAttachmentCount = cursor.getInt(10); this.setInternalDate(new Date(cursor.getLong(11))); this.setMessageId(cursor.getString(12)); mPreview = (cursor.getString(14) == null ? "" : cursor.getString(14)); if (this.mFolder == null) { LocalFolder f = new LocalFolder(cursor.getInt(13)); f.open(LocalFolder.OpenMode.READ_WRITE); this.mFolder = f; } } /* Custom version of writeTo that updates the MIME message based on localMessage * changes. */ @Override public void writeTo(OutputStream out) throws IOException, MessagingException { if (mMessageDirty) buildMimeRepresentation(); super.writeTo(out); } private void buildMimeRepresentation() throws MessagingException { if (!mMessageDirty) { return; } super.setSubject(mSubject); if (this.mFrom != null && this.mFrom.length > 0) { super.setFrom(this.mFrom[0]); } super.setReplyTo(mReplyTo); super.setSentDate(this.getSentDate()); super.setRecipients(RecipientType.TO, mTo); super.setRecipients(RecipientType.CC, mCc); super.setRecipients(RecipientType.BCC, mBcc); if (mMessageId != null) super.setMessageId(mMessageId); mMessageDirty = false; return; } public String getPreview() { return mPreview; } @Override public String getSubject() throws MessagingException { return mSubject; } @Override public void setSubject(String subject) throws MessagingException { mSubject = subject; mMessageDirty = true; } @Override public void setMessageId(String messageId) { mMessageId = messageId; mMessageDirty = true; } public int getAttachmentCount() { return mAttachmentCount; } @Override public void setFrom(Address from) throws MessagingException { this.mFrom = new Address[] { from }; mMessageDirty = true; } @Override public void setReplyTo(Address[] replyTo) throws MessagingException { if (replyTo == null || replyTo.length == 0) { mReplyTo = null; } else { mReplyTo = replyTo; } mMessageDirty = true; } /* * For performance reasons, we add headers instead of setting them (see super implementation) * which removes (expensive) them before adding them */ @Override public void setRecipients(RecipientType type, Address[] addresses) throws MessagingException { if (type == RecipientType.TO) { if (addresses == null || addresses.length == 0) { this.mTo = null; } else { this.mTo = addresses; } } else if (type == RecipientType.CC) { if (addresses == null || addresses.length == 0) { this.mCc = null; } else { this.mCc = addresses; } } else if (type == RecipientType.BCC) { if (addresses == null || addresses.length == 0) { this.mBcc = null; } else { this.mBcc = addresses; } } else { throw new MessagingException("Unrecognized recipient type."); } mMessageDirty = true; } public void setFlagInternal(Flag flag, boolean set) throws MessagingException { super.setFlag(flag, set); } public long getId() { return mId; } @Override public void setFlag(Flag flag, boolean set) throws MessagingException { /* * If a message is being marked as deleted we want to clear out it's content * and attachments as well. Delete will not actually remove the row since we need * to retain the uid for synchronization purposes. */ if (flag == Flag.DELETED && set) { delete(); } else if (flag == Flag.X_DESTROYED && set) { ((LocalFolder) mFolder).deleteAttachments(mId); mDb.execSQL("DELETE FROM messages WHERE id = ?", new Object[] { mId }); } /* * Update the unread count on the folder. */ try { LocalFolder folder = (LocalFolder)mFolder; if (flag == Flag.DELETED || flag == Flag.X_DESTROYED || (flag == Flag.SEEN && !isSet(Flag.DELETED))) { if (set && !isSet(Flag.SEEN)) { folder.setUnreadMessageCount(folder.getUnreadMessageCount() - 1); } else if (!set && isSet(Flag.SEEN)) { folder.setUnreadMessageCount(folder.getUnreadMessageCount() + 1); } } if ((flag == Flag.DELETED || flag == Flag.X_DESTROYED) && isSet(Flag.FLAGGED)) { folder.setFlaggedMessageCount(folder.getFlaggedMessageCount() + (set ? -1 : 1)); } if (flag == Flag.FLAGGED && !isSet(Flag.DELETED)) { folder.setFlaggedMessageCount(folder.getFlaggedMessageCount() + (set ? 1 : -1)); } } catch (MessagingException me) { Log.e(K9.LOG_TAG, "Unable to update LocalStore unread message count", me); throw new RuntimeException(me); } super.setFlag(flag, set); /* * Set the flags on the message. */ mDb.execSQL("UPDATE messages " + "SET flags = ? " + " WHERE id = ?", new Object[] { Utility.combine(getFlags(), ',').toUpperCase(), mId }); } private void delete() throws MessagingException { /* * Delete all of the message's content to save space. */ mDb.execSQL( "UPDATE messages SET " + "deleted = 1," + "subject = NULL, " + "sender_list = NULL, " + "date = NULL, " + "to_list = NULL, " + "cc_list = NULL, " + "bcc_list = NULL, " + "preview = NULL, " + "html_content = NULL, " + "text_content = NULL, " + "reply_to_list = NULL " + "WHERE id = ?", new Object[] { mId }); /* * Delete all of the message's attachments to save space. * We do this explicit deletion here because we're not deleting the record * in messages, which means our ON DELETE trigger for messages won't cascade */ mDb.execSQL("DELETE FROM attachments WHERE message_id = ?", new Object[] { mId }); ((LocalFolder)mFolder).deleteAttachments(mId); ((LocalFolder)mFolder).deleteHeaders(mId); } private void loadHeaders() { ArrayListmessages = new ArrayList (); messages.add(this); mHeadersLoaded = true; // set true before calling populate headers to stop recursion ((LocalFolder) mFolder).populateHeaders(messages); } @Override public void addHeader(String name, String value) { if (!mHeadersLoaded) loadHeaders(); super.addHeader(name, value); } @Override public void setHeader(String name, String value) { if (!mHeadersLoaded) loadHeaders(); super.setHeader(name, value); } @Override public String[] getHeader(String name) { if (!mHeadersLoaded) loadHeaders(); return super.getHeader(name); } @Override public void removeHeader(String name) { if (!mHeadersLoaded) loadHeaders(); super.removeHeader(name); } @Override public Set getHeaderNames() { if (!mHeadersLoaded) loadHeaders(); return super.getHeaderNames(); } } public class LocalAttachmentBodyPart extends MimeBodyPart { private long mAttachmentId = -1; public LocalAttachmentBodyPart(Body body, long attachmentId) throws MessagingException { super(body); mAttachmentId = attachmentId; } /** * Returns the local attachment id of this body, or -1 if it is not stored. * @return */ public long getAttachmentId() { return mAttachmentId; } public void setAttachmentId(long attachmentId) { mAttachmentId = attachmentId; } @Override public String toString() { return "" + mAttachmentId; } } public static class LocalAttachmentBody implements Body { private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; private Application mApplication; private Uri mUri; public LocalAttachmentBody(Uri uri, Application application) { mApplication = application; mUri = uri; } public InputStream getInputStream() throws MessagingException { try { return mApplication.getContentResolver().openInputStream(mUri); } catch (FileNotFoundException fnfe) { /* * Since it's completely normal for us to try to serve up attachments that * have been blown away, we just return an empty stream. */ return new ByteArrayInputStream(EMPTY_BYTE_ARRAY); } } public void writeTo(OutputStream out) throws IOException, MessagingException { InputStream in = getInputStream(); Base64OutputStream base64Out = new Base64OutputStream(out); IOUtils.copy(in, base64Out); base64Out.close(); } public Uri getContentUri() { return mUri; } } }