package com.samknows.ska.activity;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import com.facebook.*;
import com.samknows.measurement.SKApplication;
import com.samknows.measurement.activity.BaseLogoutActivity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.samknows.libcore.SKAndroidExportFileProvider;
import com.samknows.libcore.R;
import com.samknows.libcore.SKPorting;
import com.samknows.libcore.SKAndroidScreenShot;
public class SKAPostToSocialMedia extends BaseLogoutActivity {
// Twitter, then Facebook!
public class SocialStrings {
String twitterString;
String facebookString;
}
private ProgressDialog mProgress;
//private static final String[] PERMISSIONS = new String[] {"publish_stream", "read_stream", "offline_access"};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mProgress = new ProgressDialog(this);
}
Pair<Intent,Drawable> twitterClient = null;
Pair<Intent,Drawable> facebookClient = null;
SocialStrings mMessageToPost;
byte[] mImageToPost = null;
private void promptUserToInstallTwitterApp() {
Builder builder = new AlertDialog.Builder(SKAPostToSocialMedia.this);
builder.setTitle("Twitter app required"); // TODO - change to resource string!
builder.setMessage("To post to Twitter, you must first install the Twitter app from the Google Play Store");
builder.setPositiveButton(getString(R.string.ok_dialog), null);
AlertDialog alert = builder.create();
alert.show();
}
// http://stackoverflow.com/questions/3920640/how-to-add-icon-in-alert-dialog-before-each-item
private static class Item{
public final String text;
public final int icon;
public Item(String text, Integer icon) {
this.text = text;
this.icon = icon;
}
@Override
public String toString() {
return text;
}
}
private byte[] takeScreenshot() {
mImageToPost = null;
if (!SKApplication.getAppInstance().isSocialMediaImageExportSupported()) {
return null;
}
byte[] imageToPost = SKAndroidScreenShot.sScreenShotToByteArray(findViewById(android.R.id.content).getRootView());
mImageToPost = imageToPost;
return mImageToPost;
}
private void attachScreenshotToIntent(byte[] imageToPost, Intent intent) {
// Only get an image, if that is appropriate to the application configuration.
// For now, we push a screenshot together with the text.
// TODO - I think this will change to being a menu option
if (imageToPost != null) {
File imageFile = new File(getCacheDir(), "social.png");
FileOutputStream output = null;
try {
output = new FileOutputStream(imageFile);
output.write(imageToPost);
output.close();
output = null;
Uri uri = Uri.parse("content://" + SKAndroidExportFileProvider.sGetAUTHORITY() + "/" + imageFile.getName());
//ArrayList<Uri> uris = new ArrayList<Uri>();
//uris.add(uri);
//intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
// intent.putExtra(Intent.EXTRA_STREAM, uri);
// intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (intent != null) {
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
} catch (FileNotFoundException e) {
SKPorting.sAssert(getClass(), false);
} catch (IOException e) {
SKPorting.sAssert(getClass(), false);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
SKPorting.sAssert(getClass(), false);
}
}
}
}
}
public void postTextAndMaybeImageToSocialMedia(String selectedItem, byte[] imageToPost) {
mImageToPost = imageToPost;
if (selectedItem.equals("Twitter")) { // TODO use resource string
if (twitterClient == null || twitterClient.first == null) {
promptUserToInstallTwitterApp();
} else {
// OK!
startActivity(Intent.createChooser(twitterClient.first, "Post to Twitter"));
}
} else if (selectedItem.equals("Facebook")) { // TODO use resource string
// if (facebookClient.first == null) {
// // NOTHING to do!
// } else {
// OK!
// https://stackoverflow.com/questions/16893152/android-action-send-image-and-text
// "actually in facebook you cannot send any text from app via action send or
// actionsend multiple because this is the known bug in facebook."
// https://stackoverflow.com/questions/11593292/posting-text-image-to-facebook-from-my-app?rq=1
// "What by many android developer is classified as a bug in the facebook app is actually from their point of view a valid design decision."
// https://stackoverflow.com/questions/14244998/sharing-images-and-text-with-facebook-on-android?rq=1
// https://stackoverflow.com/questions/7545254/android-and-facebook-share-intent?rq=1
// This has yet more information on the problem!
// https://developers.facebook.com/bugs/332619626816423
// This is the main discussion, where facebook reject the issue!
//startActivity(Intent.createChooser(facebookClient.first, "Post to Facebook"));
doPostToFacebookUsingFacebookSDKButPromptFirst(mMessageToPost.facebookString, mImageToPost);
//}
}
}
public void promptUserToSelectSocialMediaAndThenPost(final SocialStrings messageToPost) {
mMessageToPost = messageToPost;
twitterClient = findTwitterClient(messageToPost.twitterString);
facebookClient = findFacebookClient(messageToPost.facebookString);
if ((twitterClient != null) && (twitterClient.first != null)) {
twitterClient.first.putExtra(Intent.EXTRA_TEXT, messageToPost.twitterString);
}
if ((facebookClient != null) && (facebookClient.first != null)) {
facebookClient.first.putExtra(Intent.EXTRA_TEXT, messageToPost.facebookString);
}
//if ((twitterClient == null && facebookClient == null)) {
//} else {
Builder builder = new AlertDialog.Builder(SKAPostToSocialMedia.this);
builder.setTitle("Choose Social Media"); // TODO - change to resource string!
// http://stackoverflow.com/questions/3920640/how-to-add-icon-in-alert-dialog-before-each-item
// Chooser with icons...
final Item[] items = {
new Item("Twitter", R.drawable.twitter), // TODO use resource string
new Item("Facebook", R.drawable.facebook) // TODO use resource string
//,new Item("...", 0),//no icon for this one
};
ListAdapter adapter = new ArrayAdapter<Item>(this,
android.R.layout.select_dialog_item,
android.R.id.text1,
items) {
public View getView(int position, View convertView, ViewGroup parent) {
//User super class to create the View
View v = super.getView(position, convertView, parent);
TextView tv = (TextView)v.findViewById(android.R.id.text1);
//Put the image on the TextView
tv.setCompoundDrawablesWithIntrinsicBounds(items[position].icon, 0, 0, 0);
//Add margin between image and text (support various screen densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
tv.setCompoundDrawablePadding(dp5);
return v;
}
};
mImageToPost = null;
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final String selectedSocialMediaItem = items[which].text;
if (SKApplication.getAppInstance().isSocialMediaImageExportSupported()) {
Builder builderImage = new AlertDialog.Builder(SKAPostToSocialMedia.this);
builderImage.setTitle(R.string.social_media_screenshot_title);
builderImage.setMessage(R.string.social_media_screenshot_message);
builderImage.setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
byte[] imageToPost = takeScreenshot();
if (imageToPost != null) {
File imageFile = new File(getCacheDir(), "social.png");
FileOutputStream output = null;
try {
output = new FileOutputStream(imageFile);
output.write(imageToPost);
output.close();
output = null;
Uri uri = Uri.parse("content://" + SKAndroidExportFileProvider.sGetAUTHORITY() + "/" + imageFile.getName());
//ArrayList<Uri> uris = new ArrayList<Uri>();
//uris.add(uri);
//intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
// intent.putExtra(Intent.EXTRA_STREAM, uri);
// intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if ((twitterClient != null) && (twitterClient.first != null)) {
String theMessageToPost = messageToPost.twitterString.replace(
getString(R.string.SocialMedia_TwitterIfUsingImage_ChangeFromThis1),
getString(R.string.SocialMedia_TwitterIfUsingImage_ChangeToThis1));
theMessageToPost = theMessageToPost.replace(
getString(R.string.SocialMedia_TwitterIfUsingImage_ChangeFromThis2),
getString(R.string.SocialMedia_TwitterIfUsingImage_ChangeToThis2));
// The replaceAll uses a regex!
theMessageToPost = theMessageToPost.replaceAll(
getString(R.string.SocialMedia_TwitterIfUsingImage_ChangeRegex4From),
getString(R.string.SocialMedia_TwitterIfUsingImage_ChangeRegex4To));
twitterClient.first.putExtra(Intent.EXTRA_TEXT, theMessageToPost);
attachScreenshotToIntent(imageToPost, twitterClient.first);
}
if ((facebookClient != null) && (facebookClient.first != null)) {
attachScreenshotToIntent(imageToPost, facebookClient.first);
}
} catch (FileNotFoundException e) {
SKPorting.sAssert(getClass(), false);
} catch (IOException e) {
SKPorting.sAssert(getClass(), false);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
SKPorting.sAssert(getClass(), false);
}
}
}
}
postTextAndMaybeImageToSocialMedia(selectedSocialMediaItem, imageToPost);
dialog.dismiss();
}
});
builderImage.setNegativeButton(getString(R.string.no_dialog),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
postTextAndMaybeImageToSocialMedia(selectedSocialMediaItem, null);
dialog.dismiss();
}
});
AlertDialog alert = builderImage.create();
alert.show();
} else {
// Social media image NOT supported!
postTextAndMaybeImageToSocialMedia(selectedSocialMediaItem, null);
}
}
});
builder.setNegativeButton(getString(R.string.cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
//}
}
// https://stackoverflow.com/questions/14051664/android-check-to-see-if-facebook-app-is-present-on-users-device
// https://stackoverflow.com/questions/6711295/how-to-check-if-facebook-is-installed-android
private Pair<Intent,Drawable> findSocialMediaClient(String appArray[], String messageToPost) {
Intent theIntent = new Intent(Intent.ACTION_SEND);
theIntent.putExtra(Intent.EXTRA_TEXT, messageToPost);
theIntent.setType("text/plain");
final PackageManager packageManager = getPackageManager();
List<ResolveInfo> list = packageManager.queryIntentActivities(theIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (String anAppArray : appArray) {
for (ResolveInfo resolveInfo : list) {
String p = resolveInfo.activityInfo.packageName;
if (p != null && p.startsWith(anAppArray)) {
theIntent.setPackage(p);
Drawable appIcon = resolveInfo.activityInfo.loadIcon(packageManager);
return new Pair<>(theIntent, appIcon);
}
}
}
return null;
}
private Pair<Intent,Drawable> findTwitterClient(String messageToPost) {
final String[] appArray = { "com.twitter.android", "com.handmark.tweetcaster", "com.seesmic", "com.thedeck.android", "com.levelup.touiteur", "com.thedeck.android.app" };
return findSocialMediaClient(appArray, messageToPost);
}
private Pair<Intent,Drawable> findFacebookClient(String messageToPost) {
final String[] appArray = { "com.facebook.katana" };
return findSocialMediaClient(appArray, messageToPost);
}
private void doPostToFacebookUsingFacebookSDKButPromptFirst(final String messageToPost, final byte[] imageToPost) {
Builder builder = new AlertDialog.Builder(SKAPostToSocialMedia.this);
builder.setTitle("Post to Facebook?"); // TODO - change to resource string!
builder.setIcon(R.drawable.facebook); // facebookClient.second);
// Add the custom layout, in which we can put data and the image!
ViewGroup myView = null;
if (imageToPost != null) {
myView = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.ska_social_media_edit_post, null);
} else {
myView = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.ska_social_media_edit_post_no_image, null);
}
final EditText editText = (EditText) myView.findViewById(R.id.editText);
if (imageToPost != null) {
ImageView imageView = (ImageView) myView.findViewById(R.id.imageView);
ByteArrayInputStream imageStream = new ByteArrayInputStream(imageToPost);
Bitmap theScreenBitmap = BitmapFactory.decodeStream(imageStream);
imageView.setImageDrawable(new BitmapDrawable(getResources(), theScreenBitmap));
}
// ... and initialise the text.
editText.setText(messageToPost);
// Now attach the layout to the AlertDialog!
builder.setView(myView); // new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
builder.setPositiveButton(getString(R.string.ok_dialog),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
doPostToFacebookUsingFacebookSDK(editText.getText().toString(), imageToPost);
dialog.dismiss();
}
});
builder.setNegativeButton(getString(R.string.cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private void doPostToFacebookUsingFacebookSDK(String messageToPost, byte[] imageToPost) {
String shortString = SKAPostToSocialMedia.this.getString(R.string.socialmedia_footer_short);
String longString = SKAPostToSocialMedia.this.getString(R.string.socialmedia_footer_long);
messageToPost = messageToPost.replace(shortString, longString);
// Change e.g. @operator to operator.
messageToPost = messageToPost.replace("@", "");
sendFacebookRequestUsingWebDialog(messageToPost, imageToPost);
/*
if (mFacebook == null) {
// Create the singleton Facebook session.
mFacebook = new Facebook(getString(R.string.facebook_app_id));
}
// Facebook
// Change the short, Twitter-specific strings... to longer, facebook specific strings.
String shortString = SKAPostToSocialMedia.this.getString(R.string.socialmedia_footer_short);
String longString = SKAPostToSocialMedia.this.getString(R.string.socialmedia_footer_long);
messageToPost = messageToPost.replace(shortString, longString);
// Change e.g. @operator to operator.
messageToPost = messageToPost.replace("@", "");
if (!mFacebook.isSessionValid()) {
// We are not yet connected - try to log-in to facebook!
// If this completes, we will automatically post the message.
mFacebook.authorize(SKAPostToSocialMedia.this, PERMISSIONS, -1, new FbLoginDialogListener());
} else {
postToFacebook(messageToPost, mImageToPost);
}
*/
}
Context getActivity() {
return this;
}
String getUriForImageToPost(byte[] imageToPost) {
File imageFile = new File(getCacheDir(), "social.png");
FileOutputStream output = null;
try {
output = new FileOutputStream(imageFile);
output.write(imageToPost);
output.close();
output = null;
Uri uri = Uri.parse("content://" + SKAndroidExportFileProvider.sGetAUTHORITY() + "/" + imageFile.getName());
//ArrayList<Uri> uris = new ArrayList<Uri>();
//uris.add(uri);
//intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
// intent.putExtra(Intent.EXTRA_STREAM, uri);
// intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
return uri.toString();
} catch (FileNotFoundException e) {
SKPorting.sAssert(getClass(), false);
} catch (IOException e) {
SKPorting.sAssert(getClass(), false);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
SKPorting.sAssert(getClass(), false);
}
}
}
return null;
}
private void createFacebookSessionAndThenPost(final String messageToPost, final byte[] imageToPost) {
// start Facebook Login
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
@Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
SKPorting.sAssert(getClass(), session == Session.getActiveSession());
postImageToActiveFacebookSession (messageToPost, imageToPost);
}
}
});
}
private void sendFacebookRequestUsingWebDialog(String messageToPost, byte[] imageToPost) {
if ( (Session.getActiveSession() != null) &&
(Session.getActiveSession().isOpened())
)
{
postImageToActiveFacebookSession (messageToPost, imageToPost);
return;
}
createFacebookSessionAndThenPost(messageToPost, imageToPost);
}
final Request.Callback uploadPhotoRequestCallback = new Request.Callback() {
@Override
public void onCompleted(Response response) {
if (response.getError() != null) {
//post error
Toast.makeText(getActivity().getApplicationContext(),
"Not posted!",
Toast.LENGTH_SHORT).show();
Toast.makeText(getActivity().getApplicationContext(),
"Please check that the Facebook app is installed, and signed-in!",
Toast.LENGTH_SHORT).show();
} else{
Toast.makeText(getActivity().getApplicationContext(),
"Message Posted!",
Toast.LENGTH_SHORT).show();
//String idRploadResponse = (String) response.getGraphObject().getProperty("id");
//if (idRploadResponse!= null) {
// String fbPhotoAddress = "https://www.facebook.com/photo.php?fbid=" +idRploadResponse;
//} else {
// //error
//}
}
}
};
//@SuppressWarnings("deprecation")
// https://stackoverflow.com/questions/20908219/how-to-post-bitmap-to-facebook-using-facebook-sdk
// https://stackoverflow.com/questions/7359173/create-bitmap-from-bytearray-in-android
public void shareBitmapToFacebook(String messageToPost, Bitmap bmp) {
//Bitmap bmp = BitmapFactory.decodeByteArray(imageToShare, 0, imageToShare.length);
if (bmp != null) {
Request request = Request.newUploadPhotoRequest(Session.getActiveSession(), bmp, uploadPhotoRequestCallback);
Bundle parameters = request.getParameters(); // <-- THIS IS IMPORTANT
parameters.putString("message", messageToPost);
// add more params here
request.setParameters(parameters);
request.executeAsync();
}
}
private void postImageToActiveFacebookSession (String messageToPost, byte[] imageToPost) {
Bitmap bmp = null;
if (imageToPost != null) {
bmp = BitmapFactory.decodeByteArray(imageToPost, 0, imageToPost.length);
}
if (bmp == null) {
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
}
shareBitmapToFacebook(messageToPost, bmp);
//bmp.recycle();
/*
Bundle params = new Bundle();
//params.putString("message", messageToPost);
//params.putString("name", messageToPost);
params.putString("name", "Facebook SDK for Android");
params.putString("caption", "Build great social apps and get more installs.");
params.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
params.putString("link", "https://developers.facebook.com/android");
if (imageToPost != null) {
String uri = getUriForImageToPost(imageToPost);
if (uri != null) {
params.putString("picture", uri);
} else {
params.putString("picture", "http://www.samknows.com/broadband/images/logo.png");
}
} else {
params.putString("picture", "http://www.samknows.com/broadband/images/logo.png");
}
// if (mImageToPost != null) {
// String uri = getUriForImageToPost(imageToPost);
// if (uri != null) {
// params.putString("picture", uri );
// }
// }
WebDialog.FeedDialogBuilder feedDialogBuilder =
new WebDialog.FeedDialogBuilder(getActivity(),
Session.getActiveSession(),
params);
feedDialogBuilder.setOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(Bundle values,
FacebookException error) {
if (error != null) {
if (error instanceof FacebookOperationCanceledException) {
Toast.makeText(getActivity().getApplicationContext(),
"Message cancelled",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity().getApplicationContext(),
"Error!",
Toast.LENGTH_SHORT).show();
}
} else {
final String requestId = values.getString("request");
if (requestId != null) {
Toast.makeText(getActivity().getApplicationContext(),
"Message posted",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity().getApplicationContext(),
"Message cancelled",
Toast.LENGTH_SHORT).show();
}
}
}
});
feedDialogBuilder.setName(messageToPost);
// if (imageToPost != null) {
// String uri = getUriForImageToPost(imageToPost);
// if (uri != null) {
// feedDialogBuilder.setPicture(uri);
// }
// }
WebDialog feedDialog = feedDialogBuilder.build();
feedDialog.show();
*/
}
final int cRequestCodeForFacebookResult = 88888888;
public void doPostToTwitterOldApproach(SocialStrings messageToPost, byte[] imageToPost) {
mMessageToPost = messageToPost;
mImageToPost = imageToPost;
Intent intent = new Intent(SKAPostToSocialMedia.this,
SKAPostToTwitterActivity.class);
// Remove the "about", to give shorter, Twitter-specific strings...
String shortString = SKAPostToSocialMedia.this.getString(R.string.socialmedia_header_short_nocarrier);
String longString = SKAPostToSocialMedia.this.getString(R.string.socialmedia_header_long_nocarrier);
messageToPost.twitterString = messageToPost.twitterString.replace(longString, shortString);
intent.putExtra("messageToPost", messageToPost.twitterString);
if (mImageToPost != null) {
intent.putExtra("imageToPost", mImageToPost);
}
startActivityForResult(intent, cRequestCodeForFacebookResult);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (Session.getActiveSession() != null) {
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
}
private Handler mRunOnUi = new Handler();
// http://stackoverflow.com/questions/7175873/click-effect-on-button-in-android?lq=1
private static final AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.7F);
public static void sSetViewOnTouchEffect(View button){
button.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
buttonClick.setDuration(500);
v.startAnimation(buttonClick);
//v.getBackground().setColorFilter(0xe0f47521,android.graphics.PorterDuff.Mode.SRC_ATOP);
v.invalidate();
break;
}
// case MotionEvent.ACTION_UP: {
// //v.getBackground().clearColorFilter();
// v.invalidate();
// break;
// }
}
return false;
}
});
}
}