/* * Copyright (c) 2012 Socialize Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.socialize.networks.facebook; import android.app.Activity; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.net.Uri; import android.util.Base64; import com.socialize.SocializeActionProxy; import com.socialize.api.SocializeSession; import com.socialize.api.action.share.SocialNetworkShareListener; import com.socialize.entity.Entity; import com.socialize.error.SocializeException; import com.socialize.listener.SocializeAuthListener; import com.socialize.networks.SocialNetwork; import com.socialize.networks.SocialNetworkPostListener; import com.socialize.networks.SocializeDeAuthListener; import java.io.IOException; import java.lang.reflect.Proxy; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Map; /** * @author Jason Polites */ public class FacebookUtils { static FacebookUtilsProxy proxy; static { proxy = (FacebookUtilsProxy) Proxy.newProxyInstance( FacebookUtilsProxy.class.getClassLoader(), new Class[]{FacebookUtilsProxy.class}, new SocializeActionProxy("facebookUtils")); // Bean name } /** * * @param context * @param listener */ public static void linkForRead (Activity context, SocializeAuthListener listener, String...permissions) { proxy.linkForRead(context, listener, permissions); } /** * * @param context * @param token * @param verifyPermissions * @param listener */ public static void linkForRead (Activity context, String token, boolean verifyPermissions, SocializeAuthListener listener, String...permissions) { proxy.linkForRead(context, token, verifyPermissions, listener, permissions); } /** * * @param context * @param listener */ public static void linkForWrite (Activity context, SocializeAuthListener listener, String...permissions) { proxy.linkForWrite(context, listener, permissions); } /** * * @param context * @param token * @param verifyPermissions * @param listener */ public static void linkForWrite (Activity context, String token, boolean verifyPermissions, SocializeAuthListener listener, String...permissions) { proxy.linkForWrite(context, token, verifyPermissions, listener, permissions); } /** * Links the current user to a facebook account. The user will be presented with the Facebook authentication dialog. * @param context The current context. * @param listener A listener to handle the result. */ @Deprecated public static void link (Activity context, SocializeAuthListener listener) { proxy.link(context, listener); } /** * Links the current user to a facebook account with custom FB permissions. The user will be presented with the Facebook authentication dialog. * @param context The current context. * @param listener A listener to handle the result. * @param permissions One or more permissions defined by http://developers.facebook.com/docs/authentication/permissions/ */ @Deprecated public static void link (Activity context, SocializeAuthListener listener, String...permissions) { proxy.link(context, listener, permissions); } /** * Links an existing Facebook access token with the current user. No authentication dialog will be shown. * @param context The current context. * @param token The Facebook access token. * @param verifyPermissions If true this method will also verify that the permissions assigned to the given token match the default permissions required by Socialize. * If not an authentication with FB will be attempted. If this parameter is false it is ASSUMED that permissions are valid. * @param listener A listener to handle the result. */ @Deprecated public static void link (Activity context, String token, boolean verifyPermissions, SocializeAuthListener listener){ proxy.link(context, token, verifyPermissions, listener); } /** * Removes the Facebook credentials from the current user. * @param context The current context. */ public static void unlink (Context context){ proxy.unlink(context, null); } /** * Removes the Facebook credentials from the current user. * @param context The current context. * @param listener */ public static void unlink (Context context, SocializeDeAuthListener listener){ proxy.unlink(context, listener); } /** * Returns true if the current user is already linked to Facebook. * @param context The current context. * @return True if the current user has linked their Facebook account. */ @Deprecated public static boolean isLinked(Context context){ return proxy.isLinked(context); } /** * * @param context * @return */ public static boolean isLinkedForRead(Context context, String...permissions){ return proxy.isLinkedForRead(context, permissions); } /** * * @param context * @return */ public static boolean isLinkedForWrite(Context context, String...permissions){ return proxy.isLinkedForWrite(context, permissions); } /** * Returns true if this application has Facebook configured. Minimum requirement is a Facebook app ID. * @param context The current context. * @return True if the Facebook has been configured for this application. */ public static boolean isAvailable(Context context){ return proxy.isAvailable(context); } /** * Sets a Facebook App ID for this application. * NOTE: This will not persist between app sessions. It is recommended that the app ID be set in socialize.properties under the key facebook.app.id * @param context The current context. * @param appId The Facebook app id, obtained from http://developers.facebook.com/apps */ public static void setAppId(Context context, String appId){ proxy.setAppId(context, appId); } /** * Returns the Facebook access token for the current user. * @return The access token or null if the user is not linked to Facebook. */ public static String getAccessToken(Context context){ return proxy.getAccessToken(context); } /** * Posts an entity to the user's Facebook wall. Post data can be customized by implementing the onBeforePost method in the given SocialNetworkListener. * @param context The current context. * @param entity The Socialize entity to which the post corresponds (Required) * @param text The text for the post. * @param listener A listnener to handle callbacks from the post. */ public static void postEntity(final Activity context, final Entity entity, final String text, final SocialNetworkShareListener listener){ if(proxy.isLinkedForWrite(context)) { proxy.postEntity(context, entity, text, listener); } else { proxy.linkForWrite(context, new SocializeAuthListener() { @Override public void onError(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } @Override public void onCancel() { if(listener != null) { listener.onCancel(); } } @Override public void onAuthSuccess(SocializeSession session) { proxy.postEntity(context, entity, text, listener); } @Override public void onAuthFail(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } }); } } /** * Calls the Facebook graph API directly with a POST. This will NOT create a share object in Socialize and is simply a raw call to Facebook. * NOTE: The current user must first be authenticated using a call to 'link'. * This method is asynchronous and can be run from the main UI thread. * @param context The current context. * @param graphPath The path on the Facebook graph api to be called for the CURRENT user. E.g. me/feed * @param params The data to be sent in the request. * @param listener A listener to handle the result. */ public static void post(final Activity context, final String graphPath, final Map<String, Object> params, final SocialNetworkPostListener listener) { if(proxy.isLinkedForWrite(context)) { proxy.post(context, graphPath, params, listener); } else { proxy.linkForWrite(context, new SocializeAuthListener() { @Override public void onError(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } @Override public void onCancel() { if(listener != null) { listener.onCancel(); } } @Override public void onAuthSuccess(SocializeSession session) { proxy.post(context, graphPath, params, listener); } @Override public void onAuthFail(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } }); } } /** * Calls the Facebook graph API directly with a GET. This will NOT create a share object in Socialize and is simply a raw call to Facebook. * NOTE: The current user must first be authenticated using a call to 'link'. * This method is asynchronous and can be run from the main UI thread. * @param context The current context. * @param graphPath The path on the Facebook graph api to be called for the CURRENT user. E.g. me/feed * @param params The data to be sent in the request. * @param listener A listener to handle the result. */ public static void get(final Activity context, final String graphPath, final Map<String, Object> params, final SocialNetworkPostListener listener) { if(proxy.isLinkedForRead(context)) { proxy.get(context, graphPath, params, listener); } else { proxy.linkForRead(context, new SocializeAuthListener() { @Override public void onError(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } @Override public void onCancel() { if(listener != null) { listener.onCancel(); } } @Override public void onAuthSuccess(SocializeSession session) { proxy.get(context, graphPath, params, listener); } @Override public void onAuthFail(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } }); } } /** * Calls the Facebook graph API directly with a DELETE. This will NOT create a share object in Socialize and is simply a raw call to Facebook. * NOTE: The current user must first be authenticated using a call to 'link'. * This method is asynchronous and can be run from the main UI thread. * @param context The current context. * @param graphPath The path on the Facebook graph api to be called for the CURRENT user. E.g. me/feed * @param params The data to be sent in the request. * @param listener A listener to handle the result. */ public static void delete(final Activity context, final String graphPath, final Map<String, Object> params, final SocialNetworkPostListener listener) { if(proxy.isLinkedForWrite(context)) { proxy.delete(context, graphPath, params, listener); } else { proxy.linkForWrite(context, new SocializeAuthListener() { @Override public void onError(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } @Override public void onCancel() { if(listener != null) { listener.onCancel(); } } @Override public void onAuthSuccess(SocializeSession session) { proxy.delete(context, graphPath, params, listener); } @Override public void onAuthFail(SocializeException error) { if(listener != null) { listener.onNetworkError(context, SocialNetwork.FACEBOOK, error); } } }); } } /** * Returns image data suitable for posting to facebook. * @param context The current context. * @param imagePath The path to the image. * @return A byte array containing the bytes to be posted. * @throws IOException */ public static byte[] getImageForPost(Activity context, Uri imagePath) throws IOException { return proxy.getImageForPost(context, imagePath); } /** * Returns image data suitable for posting to facebook. * @param context The current context. * @param image The image to be compressed. * @param format The compression format to use (one of JPEG or PNG). * @return A byte array containing the bytes to be posted. * @throws IOException */ public static byte[] getImageForPost(Activity context, Bitmap image, CompressFormat format) throws IOException { return proxy.getImageForPost(context, image, format); } /** * Extends the user's Facebook access token if needed. * @param context The current context * @param listener A listener to handle the result after re-authentication with Socialize. * @deprecated Use onResume() */ @Deprecated public static void extendAccessToken(Activity context, SocializeAuthListener listener) { proxy.extendAccessToken(context, listener); } /** * Should be called in the onResume method of any activities using Socialize. * This is called automatically by in the Socialize.onResume() method. * @param context * @param listener */ public static void onResume(Activity context, SocializeAuthListener listener) { proxy.onResume(context, listener); } /** * Retrieves the current permissions for token provided. * @param parent The current context. * @param token The token for which we are going to retrieve permissions. * @param callback A callback to handle the response. */ public static void getCurrentPermissions(Activity context, String token, OnPermissionResult callback) { proxy.getCurrentPermissions(context, token, callback); } /** * Returns the hash key used to authenticate this application with Facebook. Useful for debugging. * @param context * @return * @throws NoSuchAlgorithmException */ public static String[] getHashKeys(Activity context) throws NoSuchAlgorithmException { PackageInfo packageInfo = null; String[] keys = null; try { packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); if(packageInfo != null && packageInfo.signatures != null && packageInfo.signatures.length > 0) { keys = new String[packageInfo.signatures.length]; for (int i = 0; i < packageInfo.signatures.length; i++) { Signature signature = packageInfo.signatures[i]; MessageDigest md = MessageDigest.getInstance("SHA1"); md.update(signature.toByteArray()); String hash = new String(Base64.encode(md.digest(), 0)); keys[i] = hash; } } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return keys; } }