Android Multipart/form-data encoding for Facebook photo
android, facebook
Solution
The sample code in the documentation seems to be mistaken. It seems like all you need is a (multipart) parameter named 'source' with the image data encoded.
Below is the code from the Facebook Android SDK used to convert the Bundle values into request parameters:
public void writeObject(String key, Object value) throws IOException {
if (isSupportedParameterType(value)) {
writeString(key, parameterToString(value));
} else if (value instanceof Bitmap) {
writeBitmap(key, (Bitmap) value);
} else if (value instanceof byte[]) {
writeBytes(key, (byte[]) value);
} else if (value instanceof ParcelFileDescriptor) {
writeFile(key, (ParcelFileDescriptor) value, null);
} else if (value instanceof ParcelFileDescriptorWithMimeType) {
writeFile(key, (ParcelFileDescriptorWithMimeType) value);
} else {
throw new IllegalArgumentException("value is not a supported type: String, Bitmap, byte[]");
}
}
public void writeBitmap(String key, Bitmap bitmap) throws IOException {
writeContentDisposition(key, key, "image/png");
// Note: quality parameter is ignored for PNG
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
writeLine("");
writeRecordBoundary();
logger.appendKeyValue(" " + key, "<Image>");
}
In particular, for any Bitmaps in the Bundle, they serialize and create the appropriate multipart header for it. You can try to add your image to the Bundle as a Bitmap. Your `getImageFormData` method could then be something like:
public Bitmap getImageFormData(File image) {
return BitmapFactory.decodeFile(image.getPath());
}
You can also try supplying a `ParcelFileDescriptor`, which gets serialized in a similar fashion:
public ParcelFileDescriptor getImageFormData(File image) {
try {
return ParcelFileDescriptor.open(image, ParcelFileDescriptor.MODE_READ_ONLY);
} catch (FileNotFoundException e) {
return null;
}
}
This method may also be of interest (allows you to use url parameter instead of source):
/**
* Creates a new Request configured to upload an image to create a staging resource. Staging resources
* allow you to post binary data such as images, in preparation for a post of an Open Graph object or action
* which references the image. The URI returned when uploading a staging resource may be passed as the image
* property for an Open Graph object or action.
*
* @param session
* the Session to use, or null; if non-null, the session must be in an opened state
* @param image
* the image to upload
* @param callback
* a callback that will be called when the request is completed to handle success or error conditions
* @return a Request that is ready to execute
*/
public static Request newUploadStagingResourceWithImageRequest(Session session,
Bitmap image, Callback callback) {
Bundle parameters = new Bundle(1);
parameters.putParcelable(STAGING_PARAM, image);
return new Request(session, MY_STAGING_RESOURCES, parameters, HttpMethod.POST, callback);
}
Problem
The new Facebook Android SDK for uploading a photo to a Facebook album works like this link : ``` Bundle params = new Bundle(); params.putString("source", "{image-data}"); /* make the API call */ new Request( session, "/me/photos", params, HttpMethod.POST, new Request.Callback() { public void onCompleted(Response response) { /* handle the result */ } } ).executeAsync(); ``` What makes me confused is `{image-data}`, it said that the photo should be encoded as `multipart/form-data`, but from `params.putString("source", "{image-data}")` we can see that the second parameter of `putString()` should be a `String`, how can I encode an image file `multipart/form-data` and get the return value in`String` format? Like this: ``` public String getImageFormData(File image){ String imageValue; ... return imageValue; } ``` Or do I understand it wrong, my question now is that I have the image file, how can I use the code above to successfully upload the image to Facebook?