I've been following the tutorial to create an open graph story here. Everything works nicely, but I'd like the uploaded image to be large i.e. "user generated".
My problem is in actually implementing that. Here's the code that gets the image from the SD card:
// If uploading an image, set up the first batch request
// to do this.
// Set up image upload request parameters
Bundle imageParams = new Bundle();
Bitmap image = BitmapFactory.decodeFile(getActivity().getIntent().getStringExtra("image_for_facebook"));
// Set up the image upload request callback
Request.Callback imageCallback = new Request.Callback() {
#Override
public void onCompleted(Response response) {
// Log any response error
FacebookRequestError error = response.getError();
if (error != null) {
dismissProgressDialog();
Log.i(TAG, error.getErrorMessage());
}
}
};
// Create the request for the image upload
Request imageRequest = Request.newUploadStagingResourceWithImageRequest(Session.getActiveSession(),
image, imageCallback);
// Set the batch name so you can refer to the result
// in the follow-on object creation request
imageRequest.setBatchEntryName("imageUpload");
// Add the request to the batch
requestBatch.add(imageRequest);
And here's the bit which subsequently gives the graph object its properties:
// Set up the OpenGraphObject representing the book.
OpenGraphObject book = OpenGraphObject.Factory.createForPost("books.book");
// Set up the book image; if we uploaded the image, it is the "uri" result from the previous
// batch request, otherwise it is just a URL.
String imageUrl = "{result=imageUpload:$.uri}";
book.setImageUrls(Arrays.asList(imageUrl));
book.setTitle("A Game of Thrones");
book.setUrl("https://facemash.biz/books/a_game_of_thrones/");
book.setDescription("In the frozen wastes to the north of Winterfell, sinister and supernatural forces are mustering.");
// books.book-specific properties go under "data"
book.getData().setProperty("isbn", "0-553-57340-3");
What do I have to do to set the "user_generated" parameter of the image shown here to be true? (Assuming of course that I'm right in thinking that that's all I have to do to get a large image rather than a thumbnail).
Thanks!
Have a look at the Scrumptious sample, in SelectionFragment.java, the getImageObject method. Basically, you need to create a graph object with the "url" and the "user_generated" properties:
GraphObject imageObject = GraphObject.Factory.create();
imageObject.setProperty("url", "{result=imageUpload:$.uri}");
imageObject.setProperty("user_generated", "true");
GraphObjectList<GraphObject> images = GraphObject.Factory.createList(GraphObject.class);
images.add(imageObject);
book.setImage(images);
Ming's answer came very close for me. In order to attach an image to an OpenGraphAction, I had to do the following:
GraphObject imageObject = GraphObject.Factory.create();
imageObject.setProperty("url", imageUrl);
imageObject.setProperty("user_generated", true);
List<JSONObject> images = new ArrayList<JSONObject>();
images.add(imageObject.getInnerJSONObject());
action.setImage(images);
Open Graph Actions have the method setImage(List<JSONObject> images), but I couldn't find a setImage(GraphObjectList<GraphObject>) method. I'm using Facebook SDK v3.6, so that may have changed.
Related
I am using the Salesforce SDK (4.1.x) in a native Android app. I use the RestClient.sendAsync method to post my form data to a custom object. That part is working fine. Now I need to upload and attach a photo that was taken by the mobile user. I see that RestClient has an uploadFile method. Is this the correct method? If so then how do I connect the uploaded file to the custom form data?
Ok. I figured this out. First, create the parent object (the main form data) using the following.
request = RestRequest.getRequestForCreate(apiVersion, objectType, fields);
client.sendAsync(restRequest, new RestClient.AsyncRequestCallback() {...
In the onSuccess method you will get the id of the new object from the response. There are plenty of examples that show how to get the JSON object and the id. Armed with this parentId we can now create the attachment. The code looks something like this.
private void postImageAsAttachment(String parentId, String title) {
Map<String, Object> fields = new HashMap<String, Object>();
fields.put("Name", title);
fields.put("ParentId", parentId);
fields.put("Body", ImageHelper.getBase64FromImage(mCurrentPhotoPath));
RestRequest request = null;
try {
request = RestRequest.getRequestForCreate(apiVersion, "Attachment", fields);
} catch (Exception ex) {
Log.d(TAG, "sendRequest: ", ex);
Toast.makeText(MainActivity.this, "The file upload failed: " + ex.toString(), Toast.LENGTH_LONG).show();
}
client.sendAsync(request, new RestClient.AsyncRequestCallback() {...
I'm using a simple class called ImageHelper that simply loads the image file, performs image compression (if necessary), and base64 encodes the image data. The result is that an "Attachment" object is created as a child of the parent object.
I hope this helps the next person.
EDIT: Anwser at the end of this post.
I am trying to get a Facebook user's profile picture thanks to the inbuilt Facebook SDK's function Request().
I am using a /me/picture call to get the profile picture and convert it into a Bitmap.
The call is working fine but I don't know how to interpret and parse the result returned from Facebook
Here is the JSON that I get:
{
"FACEBOOK_NON_JSON_RESULT" : "����\u0000\u0010JFIF\u0000\u0001\u0002\u0000\u0000\u0001\u0000\u0001\u0000\u0000��\u0000\u0004*\u0000��\u0000C\u0000\u0006\u0004\u0005\u0006\u0005\u0004\u0006\u0006\u0005\u0006\u0007\u0007\u0006\b"
}
I think this should be representing the profile picture but I don't know what to do with this now.
If somebody could tell me either how to decode it, convert it to a Bitmap or what kind of data it is, I would be grateful.
NOTES: I don't want to use any other function than Request(), like DecodeStream() or an AsyncTask
Here is the answer:
When making a new Request() you need to add the "redirect" parameter to false:
Bundle params = new Bundle();
params.putBoolean("redirect", false);
This will return the correct picture URL:
{
"data":{
"is_silhouette":false,
"url":"https:\/\/fbcdn-profile-a.akamaihd.net\/hprofile-ak-xpa1\/v\/t1.0-1\/p100x100\/10312434_10152395442477210_2933994167675146084_n.jpg?oh=f3c8cb920c97fcfa4dc5e17462445cbf&oe=54404A3A&__gda__=1412730795_5f288e34e5f6e63cb1c3791dcb142880"
}
}
Try this :
ImageView user_picture;
userpicture=(ImageView)findViewById(R.id.userpicture);
URL img_value = null;
img_value = new URL("http://graph.facebook.com/"+id+"/picture?type=large");
Bitmap mIcon1 = BitmapFactory.decodeStream(img_value.openConnection().getInputStream());
userpicture.setImageBitmap(mIcon1);
Where ID is one your profile ID.
For Further details check this :
https://developers.facebook.com/docs/graph-api
I'm completely lost on this Facebook API for Android, BECAUSE THE DOCUMENTATION IS HORRIBLE!!
Even when I copy their examples to the character, (ammending to fit my app) it still doesn't work!
I have attached to my share button:
Session session = Session.getActiveSession();
if (session.isOpened()) {
OpenGraphAction action = GraphObject.Factory.create(OpenGraphAction.class);
action.setProperty("meal", "https://example.com/cooking-app/meal/Lamb-Vindaloo.html");
action.setType("feed");
Bitmap bitmap;
if (hasIcon) {
bitmap = ((BitmapDrawable)recipeIcon.getDrawable()).getBitmap();
} else {
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_special_rosemary);
}
List<Bitmap> images = new ArrayList<Bitmap>();
if (bitmap != null) {
Log.d("image!", bitmap.getByteCount() + "");
images.add(bitmap);
FacebookDialog shareDialog = new FacebookDialog.OpenGraphActionDialogBuilder(this, action, "meal")
.setImageAttachmentsForAction(images, true)
.build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else {
Log.d("no image", "");
FacebookDialog shareDialog = new FacebookDialog.OpenGraphActionDialogBuilder(this, action, "meal")
.build();
uiHelper.trackPendingDialogCall(shareDialog.present());
}
This goes through all fine, even the Log tells me the Bitmap is there, is not null, and contains a byteCount of ~160kb, but when I attach it to the share dialog it comes up with this...
01-21 00:39:30.214: E/Activity(2214): Error: com.facebook.FacebookException: Error retrieving image attachment.
What?! Is it not attaching correctly? Well, it mustn't be but this is the example copied direct from their documentation and it doesn't work! I only want to upload the current image. Poor show
Please see the reference docs for the method you're calling - https://developers.facebook.com/docs/reference/android/current/class/FacebookDialog.OpenGraphActionDialogBuilder/#setImageAttachmentFilesForAction
"In order for the images to be provided to the Facebook application as part of the app call, the NativeAppCallContentProvider must be specified correctly in the application's AndroidManifest.xml."
In NativeappCallContentProvider - https://developers.facebook.com/docs/reference/android/current/class/NativeAppCallContentProvider/ - you'll see that you need to add com.facebook.app.NativeAppCallContentProvider{FACEBOOK_APP_ID} to your manifest.
I have made a lot of combinations to get this working but I'm always getting an empty json, however in the Graph API Explorer it works very well, I'm using this statement to get the id of the albums from a X user:
SELECT aid from album WHERE owner = XXXXXXXXXX
it is returning (for example):
{
"data": [
{
"aid": "xxxxxxx_xxxx"
},
{
"aid": "xxxxxxxx_xxx"
}
]
}
in the drop down menu (where normally is Graph Api explorer selected) I have changed for my app, also I'm using the button "get access token" and selecting: "user_photos","friends_photos","user_friends" permissions,
but in my android app only I retrieve an empty json, (note: I have used another statement to recover user data (such as birthday) with this code, and works fine so code is correct, note2: I'm using the "user_photos","friends_photos","user_friends" permissions inside the app).
the code of the app (the fragment) is:
mynewbutton = (Button) view.findViewById(R.id.mynewbutton);
mynewbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
String fqlQuery = "SELECT aid from album WHERE owner = XXXXXXXXX";
Bundle params = new Bundle();
params.putString("q", fqlQuery);
Session session = Session.getActiveSession();
// params.putString("access_token", session.getAccessToken());
Request request = new Request(session,
"/fql",
params,
HttpMethod.GET,
new Request.Callback(){
public void onCompleted(Response response) {
//Log.i(TAG, "Result: " + response.toString());
}
});
Request.executeBatchAsync(request);
}
});
Possible the reason is cuz I'm not getting the "valid access_token" inside the app.
So it came some questions in mind:
1.-How do I get the access_token?
2.-Do I need to use the method getAccessToken()?
3.-If so, How do I integrate in my code?
4.-Is it necessary to change something in the Graph Api Explorer in order to get working well in the app?
5.- Am I missing something (a step or a piece of code for example)?
6.-In general, How do I get the aid from album inside my app just like in the Graph Api Explorer? thanks.
I'm trying to get the profile images of my followers for use within a ListView as thumbnails.
These thumbnails are around 125x125, but the standard twitter4j call of User.getProfileImageURL(); returns much smaller size of 48x48 and is also recommended to not be used as the image source.
I've tried creating a ProfileImage object and supplying it as a parameter, User.getProfileImageURL(profile image object.Original),
But this code takes some time to simply retrieve the url, which when loading a list of thumbnails, is inefficient.
Any suggestions on how to go about this?
Edit
Twitter API v1 has been disabled, so my old answer is no longer valid. Refer to API v1.1, which I believe requires authentication.
If you know the screen name, the twitter api allows for you to fetch the profile image at 4 different resolutions;
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=mini
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=normal
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=bigger
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=original
The "bigger" image is 73x73, which is going to interpolate in your 125x125 container. If you're not okay with this, you can try to fetch the "original" photo, but this photo could be very large (slow) and it's not necessarily a square.
Whatever method you choose, make sure you're not fetching and/or decoding Bitmaps on the UI thread. The Android API documentation has excellent guidelines for the correct way to do this.
Also we can make use of the Twitter4j using:
mTwitter.getUserProfileImage();
From the official doc:
You can obtain a user’s most recent profile image from GET users/show. Within the user object, you’ll find the profile_image_url
and profile_image_url_https fields. These fields will contain the
resized “normal” variant of the user’s uploaded image. This “normal”
variant is typically 48x48px.
By modifying the URL, you can retrieve other variant sizings such as
“bigger”, “mini”, and “original”.
Following the code:
TwitterApiClient twitterApiClient = TwitterCore.getInstance().getApiClient();
twitterApiClient.getAccountService().verifyCredentials(false, false, new Callback<User>() {
#Override
public void success(Result<User> userResult) {
String name = userResult.data.name;
String email = userResult.data.email;
// _normal (48x48px) | _bigger (73x73px) | _mini (24x24px)
String photoUrlNormalSize = userResult.data.profileImageUrl;
String photoUrlBiggerSize = userResult.data.profileImageUrl.replace("_normal", "_bigger");
String photoUrlMiniSize = userResult.data.profileImageUrl.replace("_normal", "_mini");
String photoUrlOriginalSize = userResult.data.profileImageUrl.replace("_normal", "");
}
#Override
public void failure(TwitterException exc) {
Log.d("TwitterKit", "Verify Credentials Failure", exc);
}
});
For further information refer to Twitter API Documentation | Profile Images and Banners
To create a custom size pic, for example 90x90 you can use the createScaledBitmap() method.
private final int PROFILE_PIC_SIZE = 90;
Bitmap originalPic = null;
Bitmap resizedPic = null;
try {
InputStream in = new java.net.URL(photoUrlOriginalSize).openStream();
originalPic = BitmapFactory.decodeStream(in);
resizedPic = Bitmap.createScaledBitmap(originalPic, PROFILE_PIC_SIZE, PROFILE_PIC_SIZE, false);
} catch (Exception exc) {
Log.e("Error", exc.getMessage());
exc.printStackTrace();
}
You can use getOriginalProfileImageURL() for example. This is as large as it gets.
Smaller ones are getBiggerProfileImageURL() and getProfileImageURL().
These are the urls you retrieve:
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD_normal.jpeg
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD_bigger.jpeg
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD.jpeg