Reputation: 1566
Problem: I'm trying to share content to Facebook from my Android app that is hosted somewhere else and have it deeplink back to my app.
Details I'm developing and Android app and the problem I'm facing is I have a video that I want to share to the user's newsfeed with a deeplink back in to the app. The video is hosted on Cloudinary, but that is irrelevant, trying to post a Youtube video to a users newsfeed but have it deeplink back to the app when they click on the description below would be the same problem.
I've come really close using Facebook's ShareLinkContent
and a ShareDialog
. The code looks like this:
ShareLinkContent content = new ShareLinkContent.Builder()
.setContentUrl(Uri.parse("https://kt4rh.app.goo.gl/naxy")) /* Deeplink back into my app created using Firebase Dynamic Link */
.setImageUrl(Uri.parse({path to an image stored on clodinary}))
.build();
ShareDialog shareDialog = new ShareDialog(getActivity());
shareDialog.show(content);
This shows an image, with a deeplink back to my app when the user taps on it. However, what I want to do is show a video (or a gif, either would be fine) instead of the image.
I've tried downloading the video to the device and using a ShareVideoContent
, hoping that I could set the localUrl
and the contentUrl
(similar to how I set the thumbnail and contentUrl in the ShareLinkContent
above) like this:
Uri videoUri = Uri.fromFile(new File(localPathToVideo));
ShareVideo shareVideo = new ShareVideo.Builder()
.setLocalUrl(videoUri)
.build();
ShareVideoContent videoContent = new ShareVideoContent.Builder()
.setVideo(shareVideo)
.setContentUrl(Uri.parse("https://kt4rh.app.goo.gl/naxy")) /* Deeplink back to app */
.build();
ShareDialog shareDialog = new ShareDialog(getActivity());
callbackManager = CallbackManager.Factory.create();
shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
@Override
public void onSuccess(Sharer.Result result) {}
@Override
public void onCancel() {}
@Override
public void onError(FacebookException error) {
Log.e(LOG_TAG, error.getMessage());
}
});
if (shareDialog.canShow(videoContent)) {
shareDialog.show(videoContent);
}
But I just get an error back saying "Only one of link, photos, and video should be specified.", meaning I can't set the local url and content url.
So now I'm stuck. Seems like this should be a relatively common issue (to share content hosted somewhere else and have it deeplink back to your app), but I can't figure out how to do it.
Upvotes: 0
Views: 806
Reputation: 1566
Ended up solving this by creating an html page for every item to be shared (in this case trip itineraries) and hosting them on Firebase's Cloud Storage. Here's what the code looks like
/**
* In order to share gifs to facebook and have a animating gif show up, we need to construct an arbitrary HTML page that wraps the
* gif image that we want to share. When the user clicks on the wrapped html page, it will forward to the real page we want it to show.
*
* Facebook uses custom meta properties to determine what image to show in the preview, which is why we need to wrap the actual gif with another image this way
*/
private static final String GIF_IMAGE = "<gif_image_here>";
private static final String REDIRECT_LINK = "<redirect_link_here>";
private static final String SHARE_HTML_PAGE = "<!DOCTYPE html><html>" +
"<head>" +
"<meta property=\"og:type\" content=\"video.other\" />" +
"<meta property=\"og:url\" content=\"" + GIF_IMAGE + "\" />" +
"<meta property=\"og:image\" content=\"" + GIF_IMAGE + "\" />" +
"<meta http-equiv=\"refresh\" content=\"0; url=" + REDIRECT_LINK + "\" />" +
"</head></html>";
public static void shareGifToFacebook(final Activity activity, final String gifUrl, final Trip trip, final ShareStatusListener shareStatusListener) {
String htmlPageToShare = SHARE_HTML_PAGE.replaceAll(GIF_IMAGE, gifUrl).replaceAll(REDIRECT_LINK, DeeplinkUtils.getTripDeeplink(trip.getUid()));
// Upload the html page somewhere accessible
FirebaseStorageUploader.uploadShareHtml(TravellerManager.getInstance().getCurrentlyLoggedInUserUid(), htmlPageToShare, new FirebaseStorageUploader.UploadShareHtmlListener() {
@Override
public void onSuccess(String publicUrl) {
Log.d("ShareUtils", "shareGifToFacebook() publicUrl to be shortened: " + publicUrl);
URLShortener.shortUrl(publicUrl, new URLShortener.LoadingCallback() {
@Override
public void startedLoading() {
}
@Override
public void finishedLoading(@Nullable String shortUrl) {
Log.d("ShareUtils", "shareGifToFacebook() finishedLoading() shortenedUrl " + shortUrl);
ShareLinkContent content = new ShareLinkContent.Builder()
.setContentUrl(Uri.parse(shortUrl))
.setContentDescription(activity.getString(R.string.view_trip_on_wd))
.setContentTitle(trip.getName())
.build();
ShareDialog shareDialog = new ShareDialog(activity);
shareDialog.show(content);
if (shareStatusListener != null) {
shareStatusListener.onShared();
}
}
});
}
@Override
public void onFailed() {
Toaster.toastLong(activity.getString(R.string.general_error));
}
});
}
Upvotes: 1
Reputation: 99
I think on Android you can't set the contentUrl
and the Video simultaneously. I was getting the similar issue, but it worked after removing .setContentUrl(...)
.
What you could do instead is copy the link to the clipboard and convince the user to paste the link into their caption (i.e.: show a pop-up / alert before opening up the ShareDialog
).
There may be other ways around this. If so, I would love to know as well.
Hope this helps.
Upvotes: 0