/** * Save the tag data into the JPEG file. This is expensive because it involves copying all the JPG * data from one file to another and deleting the old file and renaming the other. It's best to * use {@link #setAttribute(String,String)} to set all attributes to write and make a single call * rather than multiple calls for each attribute. */ public void saveAttributes() throws IOException { // format of string passed to native C code: // "attrCnt attr1=valueLen value1attr2=value2Len value2..." // example: // "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO" StringBuilder sb = new StringBuilder(); int size = mAttributes.size(); if (mAttributes.containsKey("hasThumbnail")) { --size; } sb.append(size + " "); for (Map.Entry<String, String> iter : mAttributes.entrySet()) { String key = iter.getKey(); if (key.equals("hasThumbnail")) { // this is a fake attribute not saved as an exif tag continue; } String val = iter.getValue(); sb.append(key + "="); sb.append(val.length() + " "); sb.append(val); } String s = sb.toString(); synchronized (sLock) { saveAttributesNative(mFilename, s); commitChangesNative(mFilename); } }