Loading android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java 100755 → 100644 +22 −6 Original line number Diff line number Diff line Loading @@ -451,6 +451,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { public boolean vcard21; public byte[] filter; public boolean ignorefilter; public AppParamValue() { maxListCount = 0xFFFF; listStartOffset = 0; Loading @@ -459,6 +463,9 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { order = ""; needTag = 0x00; vcard21 = true; //Filter is not set by default ignorefilter = true; filter = new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} ; } public void dump() { Loading @@ -473,10 +480,17 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { AppParamValue appParamValue) { int i = 0; boolean parseOk = true; while (i < appParam.length) { while ((i < appParam.length) && (parseOk == true)) { switch (appParam[i]) { case ApplicationParameter.TRIPLET_TAGID.FILTER_TAGID: i += 2; // length and tag field in triplet for (int index=0; index < ApplicationParameter.TRIPLET_LENGTH.FILTER_LENGTH; index++) { if (appParam[i+index] != 0){ appParamValue.ignorefilter = false; appParamValue.filter[index] = appParam[i+index]; } } i += ApplicationParameter.TRIPLET_LENGTH.FILTER_LENGTH; break; case ApplicationParameter.TRIPLET_TAGID.ORDER_TAGID: Loading Loading @@ -854,7 +868,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return pushBytes(op, ownerVcard); } else { return mVcardManager.composeAndSendPhonebookOneVcard(op, intIndex, vcard21, null, mOrderBy ); mOrderBy, appParamValue.ignorefilter, appParamValue.filter); } } else { if (intIndex <= 0 || intIndex > size) { Loading @@ -865,7 +879,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // begin from 1.vcf if (intIndex >= 1) { return mVcardManager.composeAndSendCallLogVcards(appParamValue.needTag, op, intIndex, intIndex, vcard21); intIndex, intIndex, vcard21, appParamValue.ignorefilter, appParamValue.filter); } } return ResponseCodes.OBEX_HTTP_OK; Loading Loading @@ -926,15 +941,16 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return pushBytes(op, ownerVcard); } else { return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, ownerVcard); ownerVcard, appParamValue.ignorefilter, appParamValue.filter); } } else { return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, vcard21, null); vcard21, null, appParamValue.ignorefilter, appParamValue.filter); } } else { return mVcardManager.composeAndSendCallLogVcards(appParamValue.needTag, op, startPoint + 1, endPoint + 1, vcard21); startPoint + 1, endPoint + 1, vcard21, appParamValue.ignorefilter, appParamValue.filter); } } Loading android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java +308 −9 Original line number Diff line number Diff line Loading @@ -341,7 +341,8 @@ public class BluetoothPbapVcardManager { } public final int composeAndSendCallLogVcards(final int type, Operation op, final int startPoint, final int endPoint, final boolean vcardType21) { final int startPoint, final int endPoint, final boolean vcardType21, boolean ignorefilter, byte[] filter) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading Loading @@ -401,11 +402,12 @@ public class BluetoothPbapVcardManager { if (V) Log.v(TAG, "Call log query selection is: " + selection); return composeAndSendVCards(op, selection, vcardType21, null, false); return composeAndSendVCards(op, selection, vcardType21, null, false, ignorefilter, filter); } public final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, final boolean vcardType21, String ownerVCard) { final int endPoint, final boolean vcardType21, String ownerVCard, boolean ignorefilter, byte[] filter) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading Loading @@ -449,11 +451,13 @@ public class BluetoothPbapVcardManager { if (V) Log.v(TAG, "Query selection is: " + selection); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true, ignorefilter, filter); } public final int composeAndSendPhonebookOneVcard(Operation op, final int offset, final boolean vcardType21, String ownerVCard, int orderByWhat) { final boolean vcardType21, String ownerVCard, int orderByWhat, boolean ignorefilter, byte[] filter) { if (offset < 1) { Log.e(TAG, "Internal error: offset is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading Loading @@ -504,16 +508,22 @@ public class BluetoothPbapVcardManager { if (V) Log.v(TAG, "Query selection is: " + selection); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true, ignorefilter, filter); } public final int composeAndSendVCards(Operation op, final String selection, final boolean vcardType21, String ownerVCard, boolean isContacts) { final boolean vcardType21, String ownerVCard, boolean isContacts, boolean ignorefilter, byte[] filter) { long timestamp = 0; if (V) timestamp = System.currentTimeMillis(); if (isContacts) { VCardComposer composer = null; FilterVcard vcardfilter= new FilterVcard(); if (!ignorefilter) { vcardfilter.setFilter(filter); } HandlerForStringBuffer buffer = null; try { // Currently only support Generic Vcard 2.1 and 3.0 Loading @@ -523,8 +533,7 @@ public class BluetoothPbapVcardManager { } else { vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; } if (!BluetoothPbapConfig.includePhotosInVcard()) { if (!vcardfilter.isPhotoEnabled()) { vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; } Loading Loading @@ -565,6 +574,11 @@ public class BluetoothPbapVcardManager { + composer.getErrorReason()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } Log.v (TAG , "vCard from composer: " + vcard); if (!ignorefilter) { vcard = vcardfilter.applyFilter(vcard, vcardType21); Log.v (TAG , "vCard on applying filter: " + vcard); } vcard = StripTelephoneNumber(vcard); if (V) { Log.v(TAG, "Vcard Entry:"); Loading Loading @@ -709,4 +723,289 @@ public class BluetoothPbapVcardManager { } } } public class FilterVcard{ public FilterVcard(){ }; private final int FN_BIT = 1; private boolean fn = true; private final int PHOTO_BIT = 3; private boolean photo = true; //BDAY falls under events private final int BDAY_BIT = 4; private boolean bday = true; private final int ADR_BIT = 5; private boolean adr = true; private final int EMAIL_BIT = 8; private boolean email = true; private final int TITLE_BIT = 12; private boolean title = true; private final int ORG_BIT = 16; private boolean org = true; private final int NOTES_BIT = 17; private boolean notes = true; private final int URL_BIT = 20; private boolean url = true; private final int NICKNAME_BIT = 23; private boolean nickname = true; public void setFilter(byte[] filter){ fn = checkbit(FN_BIT, filter); photo = checkbit(PHOTO_BIT, filter); bday = checkbit(BDAY_BIT, filter); adr = checkbit(ADR_BIT, filter); email = checkbit(EMAIL_BIT, filter); title = checkbit(TITLE_BIT, filter); org = checkbit(ORG_BIT, filter); notes = checkbit(NOTES_BIT, filter); url = checkbit(URL_BIT, filter); nickname = checkbit(NICKNAME_BIT, filter); } private boolean checkbit (int attr_bit, byte[] filter){ int filterlen = filter.length; if( ((filter[filterlen -1 -((int)attr_bit/8)] >> (attr_bit%8)) & 0x01) == 0) { return false; } return true; } public boolean isPhotoEnabled(){ return photo; } private boolean checkValidFilter (String attr) { if((attr.startsWith("N:")) || (attr.startsWith("TEL")) || (attr.startsWith("VERSION")) || (attr.startsWith("URL")) || (attr.startsWith("FN")) || (attr.startsWith("BDAY")) || (attr.startsWith("ADR")) || (attr.startsWith("EMAIL")) || (attr.startsWith("TITLE")) || (attr.startsWith("ORG")) || (attr.startsWith("NOTE")) || (attr.startsWith("NICKNAME"))) { return true; } return false; } public String applyFilter ( String vCard, boolean vCardType21){ String attr [] = vCard.split(System.getProperty("line.separator")); String filteredVcard = ""; //FN is not the mandatory field in 2.1 vCard if(((!fn) && (vCardType21)) && (vCard.contains("FN"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("FN")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } //NOTE: No need to check photo, we already refrained it if it is not set in the filter if((!bday) && (vCard.contains("BDAY"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("BDAY")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!adr) && (vCard.contains("ADR"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("ADR")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!email) && (vCard.contains("EMAIL"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("EMAIL")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!title) && (vCard.contains("TITLE"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("TITLE")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!org) && (vCard.contains("ORG"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("ORG")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!notes) && (vCard.contains("NOTE"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("NOTE")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } /*Nickname is not supported in 2.1 version. *Android still ads it for 2.1 with nickname mentioned in lower case, and therefore *we need to check for both cases. */ if(((!nickname) || (vCardType21)) && (vCard.contains("NICKNAME"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("NICKNAME")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!url) && (vCard.contains("URL"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("URL")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } /*Since PBAP does not have filter bit for IM and SIP, *removing them by default. */ if(vCard.toUpperCase().contains("IM")) { for (int i=0; i < attr.length; i++) { if(attr[i].toUpperCase().contains("IM")){ vCard = vCard.replace(attr[i] + "\n", ""); } } } if(vCard.toUpperCase().contains("SIP")) { for (int i=0; i < attr.length; i++) { if(attr[i].toUpperCase().contains("SIP")){ vCard = vCard.replace(attr[i] + "\n", ""); } } } Log.v(TAG, "Tokens after applying filter: "); for (int i=0; i < attr.length; i++) { if(!attr[i].equals("")){ filteredVcard = filteredVcard.concat(attr[i] + "\n"); } } return filteredVcard; } } } Loading
android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java 100755 → 100644 +22 −6 Original line number Diff line number Diff line Loading @@ -451,6 +451,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { public boolean vcard21; public byte[] filter; public boolean ignorefilter; public AppParamValue() { maxListCount = 0xFFFF; listStartOffset = 0; Loading @@ -459,6 +463,9 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { order = ""; needTag = 0x00; vcard21 = true; //Filter is not set by default ignorefilter = true; filter = new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} ; } public void dump() { Loading @@ -473,10 +480,17 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { AppParamValue appParamValue) { int i = 0; boolean parseOk = true; while (i < appParam.length) { while ((i < appParam.length) && (parseOk == true)) { switch (appParam[i]) { case ApplicationParameter.TRIPLET_TAGID.FILTER_TAGID: i += 2; // length and tag field in triplet for (int index=0; index < ApplicationParameter.TRIPLET_LENGTH.FILTER_LENGTH; index++) { if (appParam[i+index] != 0){ appParamValue.ignorefilter = false; appParamValue.filter[index] = appParam[i+index]; } } i += ApplicationParameter.TRIPLET_LENGTH.FILTER_LENGTH; break; case ApplicationParameter.TRIPLET_TAGID.ORDER_TAGID: Loading Loading @@ -854,7 +868,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return pushBytes(op, ownerVcard); } else { return mVcardManager.composeAndSendPhonebookOneVcard(op, intIndex, vcard21, null, mOrderBy ); mOrderBy, appParamValue.ignorefilter, appParamValue.filter); } } else { if (intIndex <= 0 || intIndex > size) { Loading @@ -865,7 +879,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // begin from 1.vcf if (intIndex >= 1) { return mVcardManager.composeAndSendCallLogVcards(appParamValue.needTag, op, intIndex, intIndex, vcard21); intIndex, intIndex, vcard21, appParamValue.ignorefilter, appParamValue.filter); } } return ResponseCodes.OBEX_HTTP_OK; Loading Loading @@ -926,15 +941,16 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return pushBytes(op, ownerVcard); } else { return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, ownerVcard); ownerVcard, appParamValue.ignorefilter, appParamValue.filter); } } else { return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, vcard21, null); vcard21, null, appParamValue.ignorefilter, appParamValue.filter); } } else { return mVcardManager.composeAndSendCallLogVcards(appParamValue.needTag, op, startPoint + 1, endPoint + 1, vcard21); startPoint + 1, endPoint + 1, vcard21, appParamValue.ignorefilter, appParamValue.filter); } } Loading
android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java +308 −9 Original line number Diff line number Diff line Loading @@ -341,7 +341,8 @@ public class BluetoothPbapVcardManager { } public final int composeAndSendCallLogVcards(final int type, Operation op, final int startPoint, final int endPoint, final boolean vcardType21) { final int startPoint, final int endPoint, final boolean vcardType21, boolean ignorefilter, byte[] filter) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading Loading @@ -401,11 +402,12 @@ public class BluetoothPbapVcardManager { if (V) Log.v(TAG, "Call log query selection is: " + selection); return composeAndSendVCards(op, selection, vcardType21, null, false); return composeAndSendVCards(op, selection, vcardType21, null, false, ignorefilter, filter); } public final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, final boolean vcardType21, String ownerVCard) { final int endPoint, final boolean vcardType21, String ownerVCard, boolean ignorefilter, byte[] filter) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading Loading @@ -449,11 +451,13 @@ public class BluetoothPbapVcardManager { if (V) Log.v(TAG, "Query selection is: " + selection); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true, ignorefilter, filter); } public final int composeAndSendPhonebookOneVcard(Operation op, final int offset, final boolean vcardType21, String ownerVCard, int orderByWhat) { final boolean vcardType21, String ownerVCard, int orderByWhat, boolean ignorefilter, byte[] filter) { if (offset < 1) { Log.e(TAG, "Internal error: offset is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading Loading @@ -504,16 +508,22 @@ public class BluetoothPbapVcardManager { if (V) Log.v(TAG, "Query selection is: " + selection); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true); return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true, ignorefilter, filter); } public final int composeAndSendVCards(Operation op, final String selection, final boolean vcardType21, String ownerVCard, boolean isContacts) { final boolean vcardType21, String ownerVCard, boolean isContacts, boolean ignorefilter, byte[] filter) { long timestamp = 0; if (V) timestamp = System.currentTimeMillis(); if (isContacts) { VCardComposer composer = null; FilterVcard vcardfilter= new FilterVcard(); if (!ignorefilter) { vcardfilter.setFilter(filter); } HandlerForStringBuffer buffer = null; try { // Currently only support Generic Vcard 2.1 and 3.0 Loading @@ -523,8 +533,7 @@ public class BluetoothPbapVcardManager { } else { vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; } if (!BluetoothPbapConfig.includePhotosInVcard()) { if (!vcardfilter.isPhotoEnabled()) { vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; } Loading Loading @@ -565,6 +574,11 @@ public class BluetoothPbapVcardManager { + composer.getErrorReason()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } Log.v (TAG , "vCard from composer: " + vcard); if (!ignorefilter) { vcard = vcardfilter.applyFilter(vcard, vcardType21); Log.v (TAG , "vCard on applying filter: " + vcard); } vcard = StripTelephoneNumber(vcard); if (V) { Log.v(TAG, "Vcard Entry:"); Loading Loading @@ -709,4 +723,289 @@ public class BluetoothPbapVcardManager { } } } public class FilterVcard{ public FilterVcard(){ }; private final int FN_BIT = 1; private boolean fn = true; private final int PHOTO_BIT = 3; private boolean photo = true; //BDAY falls under events private final int BDAY_BIT = 4; private boolean bday = true; private final int ADR_BIT = 5; private boolean adr = true; private final int EMAIL_BIT = 8; private boolean email = true; private final int TITLE_BIT = 12; private boolean title = true; private final int ORG_BIT = 16; private boolean org = true; private final int NOTES_BIT = 17; private boolean notes = true; private final int URL_BIT = 20; private boolean url = true; private final int NICKNAME_BIT = 23; private boolean nickname = true; public void setFilter(byte[] filter){ fn = checkbit(FN_BIT, filter); photo = checkbit(PHOTO_BIT, filter); bday = checkbit(BDAY_BIT, filter); adr = checkbit(ADR_BIT, filter); email = checkbit(EMAIL_BIT, filter); title = checkbit(TITLE_BIT, filter); org = checkbit(ORG_BIT, filter); notes = checkbit(NOTES_BIT, filter); url = checkbit(URL_BIT, filter); nickname = checkbit(NICKNAME_BIT, filter); } private boolean checkbit (int attr_bit, byte[] filter){ int filterlen = filter.length; if( ((filter[filterlen -1 -((int)attr_bit/8)] >> (attr_bit%8)) & 0x01) == 0) { return false; } return true; } public boolean isPhotoEnabled(){ return photo; } private boolean checkValidFilter (String attr) { if((attr.startsWith("N:")) || (attr.startsWith("TEL")) || (attr.startsWith("VERSION")) || (attr.startsWith("URL")) || (attr.startsWith("FN")) || (attr.startsWith("BDAY")) || (attr.startsWith("ADR")) || (attr.startsWith("EMAIL")) || (attr.startsWith("TITLE")) || (attr.startsWith("ORG")) || (attr.startsWith("NOTE")) || (attr.startsWith("NICKNAME"))) { return true; } return false; } public String applyFilter ( String vCard, boolean vCardType21){ String attr [] = vCard.split(System.getProperty("line.separator")); String filteredVcard = ""; //FN is not the mandatory field in 2.1 vCard if(((!fn) && (vCardType21)) && (vCard.contains("FN"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("FN")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } //NOTE: No need to check photo, we already refrained it if it is not set in the filter if((!bday) && (vCard.contains("BDAY"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("BDAY")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!adr) && (vCard.contains("ADR"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("ADR")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!email) && (vCard.contains("EMAIL"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("EMAIL")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!title) && (vCard.contains("TITLE"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("TITLE")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!org) && (vCard.contains("ORG"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("ORG")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!notes) && (vCard.contains("NOTE"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("NOTE")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } /*Nickname is not supported in 2.1 version. *Android still ads it for 2.1 with nickname mentioned in lower case, and therefore *we need to check for both cases. */ if(((!nickname) || (vCardType21)) && (vCard.contains("NICKNAME"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("NICKNAME")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } if((!url) && (vCard.contains("URL"))) { for (int i=0; i < attr.length; i++) { if(attr[i].startsWith("URL")){ attr[i] = ""; /** Remove multiline Content, if any */ /** End traversal before END:VCARD */ for (int j = i+1; j < attr.length - 1; j++) { if (checkValidFilter(attr[j])) { break; } else { /** Continuation of above attribute, remove */ attr[j] = ""; } } } } } /*Since PBAP does not have filter bit for IM and SIP, *removing them by default. */ if(vCard.toUpperCase().contains("IM")) { for (int i=0; i < attr.length; i++) { if(attr[i].toUpperCase().contains("IM")){ vCard = vCard.replace(attr[i] + "\n", ""); } } } if(vCard.toUpperCase().contains("SIP")) { for (int i=0; i < attr.length; i++) { if(attr[i].toUpperCase().contains("SIP")){ vCard = vCard.replace(attr[i] + "\n", ""); } } } Log.v(TAG, "Tokens after applying filter: "); for (int i=0; i < attr.length; i++) { if(!attr[i].equals("")){ filteredVcard = filteredVcard.concat(attr[i] + "\n"); } } return filteredVcard; } } }