Skip to content

Commit

Permalink
Added support for Facebook SDK 3.0 beta for Android. Modified Hackboo…
Browse files Browse the repository at this point in the history
…k to split read and write permissions to make this line up with the Android 3.0 and iOS 3.1 requirements.
  • Loading branch information
Christine Abernathy committed Nov 1, 2012
1 parent 7204c5a commit 881585f
Show file tree
Hide file tree
Showing 7 changed files with 347 additions and 313 deletions.
27 changes: 9 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ To use this plugin you will need to make sure you've registered your Facebook ap

If you plan on rolling this out on iOS, please note that you will need to ensure that you have properly set up your Native iOS App settings on the [Facebook App Dashboard](http://developers.facebook.com/apps). Please see the [Getting Started with the Facebook SDK](https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/3.1/): Create a Facebook App section, for more details on this.

If you plan on rolling this out on Android, please note that you will need to [generate a hash of your Android key(s) and submit those to the Developers page on Facebook](http://developers.facebook.com/docs/mobile/android/build/#sig) to get it working. Furthermore, if you are generating this hash on Windows (specifically 64 bit versions), please use version 0.9.8e or 0.9.8d of [OpenSSL for Windows](http://code.google.com/p/openssl-for-windows/downloads/list) and *not* 0.9.8k. Big ups to [fernandomatos](http://github.com/fernandomatos) for pointing this out!
If you plan on rolling this out on Android, please note that you will need to [generate a hash of your Android key(s) and submit those to the Developers page on Facebook](https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/) to get it working. Furthermore, if you are generating this hash on Windows (specifically 64 bit versions), please use version 0.9.8e or 0.9.8d of [OpenSSL for Windows](http://code.google.com/p/openssl-for-windows/downloads/list) and *not* 0.9.8k. Big ups to [fernandomatos](http://github.com/fernandomatos) for pointing this out!

# Project Structure

Expand Down Expand Up @@ -49,28 +49,19 @@ If you plan on rolling this out on Android, please note that you will need to [g

## Android

View the [Video](http://www.youtube.com/watch?v=mlpBgWiel2w)

1. [Create a basic Cordova Android application](http://docs.phonegap.com/en/2.1.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android).
* NOTE: Min Target has to be set to 8. The plugin has an issue if you set your minimum target higher than that. You can edit this in your android manifest file.

2. In the Cordova Android application you will need to put the following in your `res/xml/config.xml` file as a child to the plugin tag: <pre>&lt;plugin name="org.apache.cordova.facebook.Connect" value="org.apache.cordova.facebook.ConnectPlugin" /&gt;</pre>

3. You'll need to build + include the Facebook Android SDK and include the
Facebook JavaScript SDK:
* First run `git submodule update --init` to initialize and pull down
the version of the Android Facebook SDK that works with this plugin; it will end up under `lib/`. Copy the src and res folders from lib/facebook-android-sdk/facebook/ into the root of your Cordova Android application. It should merge with the existing src and res folders and not overwrite.
* NOTE: I haven't been able to compile the facebook android SDK into a
jar with success. So, I just copied the source into my generated
Cordova application directory and imported the generated Cordova
Android package as an import at the top of FbDialog.java.

TODO: Fix this
:P. `cd facebook-android-sdk/facebook` and run `jar cf
facebook-android-sdk.jar src`. This will create a
`facebook-android-sdk.jar` file that you need to copy into your
generated Cordova-Android's `libs` directory (and also add to your
build path).
3. You'll need to set up the Facebook SDK for Android:
* [Install the Facebook SDK for Android and the Facebook APK](https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/)
* [Import the Facebook SDK into Eclipse](https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/)
* Link the Facebook SDK library to your project. View the properties for the project, and navigate to the 'Android' tab. In the lower part of the dialog, click 'Add' and choose the 'FacebookSDK' project from the workspace.
* Add a new activity to your app to handle Facebook Login. Open up your `AndroidManifest.xml` file and add this additional activity:

<activity android:name="com.facebook.LoginActivity"
android:label="@string/app_name" />

4. From the Cordova Facebook Connect Plugin folder copy the src folder from `native/android/` folder into the root of your Cordova Android application. It should merge with the existing src folder.

Expand Down
57 changes: 0 additions & 57 deletions example/HackBook/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@ body.not_connected .show_when_connected {
display: none;
}

body.permissioned .show_when_not_connected {
display: none;
}

body.not_permissioned .show_when_not_connected {
display: none;
}

body.permissioned #extended_permission_button {
display: none;
}

body.not_permissioned #extended_permission_button {
display: block;
}

#action {
display: none;
position: fixed;
Expand Down Expand Up @@ -255,39 +239,6 @@ h1 {
text-align: center;
}


body.permissioned .show_when_not_permissioned {
display: none;
}

body .show_when_not_permissioned {
display: none;
}

body .show_when_permissioned {
display: block;
}

body.permissioned .show_when_permissioned {
display: block;
}

body.not_permissioned .show_when_not_permissioned {
display: block;
}

body.not_permissioned .show_when_permissioned {
display: none;
}

body.not_connected .show_when_not_permissioned {
display: block;
}

body.not_connected .show_when_permissioned {
display: none;
}

#fb-content {
margin-top: 10px;
}
Expand Down Expand Up @@ -391,14 +342,6 @@ body.connected .info-requires-connect {
display: none;
}

body.not_permissioned .info-requires-connect {
display: none;
}

body.permissioned .info-requires-connect {
display: none;
}

.place .check-in-msg {
float: left;
clear: both;
Expand Down
37 changes: 23 additions & 14 deletions example/HackBook/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,19 @@ <h1>Asking for extended permissions</h1>
If your app needs more than this basic information to function, you must request specific permissions from the user.
For example, you might prompt the user to grant access to their Likes in order to recommend related content for them.
</p>

<div id="disabled_perm_user_likes">
<div id="extended_permission_button" class="button button-requires-connect" onclick="promptPermission('user_likes')" />Grant the 'user_likes' permission</div>

<div id="extended_permission_button" class="button button-requires-connect" onclick="promptExtendedPermissions()" />Grant the 'user_likes' permission</div>

<div class="info-requires-connect">You need to login before you can use this functionality.</div>
<div class="info-requires-connect">You need to login before you can use this functionality.</div>
</div>
<div id="enabled_perm_user_likes">
<div class="show_when_connected">
<p>
You've already granted the user_likes permission previously so the button isn't shown.
</p>
</div>
</div>
</div>
</div>

Expand Down Expand Up @@ -231,14 +240,14 @@ <h1>Get user's recent check-ins</h1>

<div id="checkins"></div>

<div class="show_when_not_permissioned">
<div class="button button-requires-connect" onclick="promptCheckInPermission()" />Grant check-in permission</div>

<div class="info-requires-connect">You need to login before you can use this functionality.</div>
<div id="disabled_perm_user_status">
<div class="button button-requires-connect" onclick="promptPermission('user_status')" />Grant check-in permission</div>
<div class="info-requires-connect">You need to login before you can use this functionality.</div>
</div>

<div class="show_when_permissioned">
<div class="button" onclick="getCheckIns();hideButton(this);"/>Get past check-ins</div>
<div id="enabled_perm_user_status">
<div class="button button-requires-connect" onclick="getCheckIns();hideButton(this);"/>Get past check-ins</div>
</div>
</div>

Expand All @@ -250,14 +259,14 @@ <h1>Check the user into a place</h1>

<div id="locations-nearby"></div>

<div class="show_when_not_permissioned">
<div class="button button-requires-connect" onclick="promptCheckInPermission()" />Grant check-in permission</div>
<div id="disabled_perm_publish_checkins">
<div class="button button-requires-connect" onclick="promptPermission('publish_checkins')" />Grant publish check-in permission</div>

<div class="info-requires-connect">You need to login before you can use this functionality.</div>
</div>

<div class="show_when_permissioned">
<div class="button" onclick="getNearby();hideButton(this);" />Find nearby locations</div>
<div id="enabled_perm_publish_checkins">
<div class="button button-requires-connect" onclick="getNearby();hideButton(this);" />Find nearby locations</div>
</div>
</div>
</div>
Expand Down
5 changes: 4 additions & 1 deletion example/HackBook/js/_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ window.fbAsyncInit = function() {
useCachedDialogs: true,
oauth: true
});


FB.getLoginStatus(handleStatusChange);

authUser();
checkForCredits();
updateAuthElements();
};


// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
Expand Down
83 changes: 58 additions & 25 deletions example/HackBook/js/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@

var user = [];

var permissions = ['user_status', 'publish_checkins', 'user_likes'];

//Detect when Facebook tells us that the user's session has been returned
function authUser() {
FB.Event.subscribe('auth.statusChange', handleStatusChange);
}

// Handle status changes
function handleStatusChange(session) {
console.log('Got the user\'s session: ', session);
console.log('Got the user\'s session: ' + JSON.stringify(session));

if (session.authResponse) {
document.body.className = 'connected';
Expand All @@ -26,55 +29,85 @@ function handleStatusChange(session) {
if (!response.error) {
user = response;

console.log('Got the user\'s name and picture: ');
console.log(response);
console.log('Got the user\'s name and picture: ' + JSON.stringify(response));

//Update display of user name and picture
if (document.getElementById('user-name')) {
document.getElementById('user-name').innerHTML = user.name;
}
if (document.getElementById('user-picture')) {
if (user.picture.data) {
document.getElementById('user-picture').src = user.picture.data.url;
} else {
document.getElementById('user-picture').src = user.picture;
}
document.getElementById('user-picture').src = user.picture.data.url;
}
}

clearAction();
});
} else {
}
else {
document.body.className = 'not_connected';

clearAction();
}
}

//Check the current permissions to set the page elements.
//Pass back a flag to check for a specific permission, to
//handle the cancel detection flow.
function checkUserPermissions(permissionToCheck) {
var permissionsFQLQuery = 'SELECT ' + permissions.join() + ' FROM permissions WHERE uid = me()';
FB.api('/fql', { q: permissionsFQLQuery },
function(response) {
if (document.body.className != 'not_connected') {
for (var i = 0; i < permissions.length; i++) {
var perm = permissions[i];
var enabledElementName = document.getElementById('enabled_perm_' + perm);
var disabledElementName = document.getElementById('disabled_perm_' + perm);
if (response.data[0][perm] == 1) {
enabledElementName.style.display = 'block';
disabledElementName.style.display = 'none';
} else {
enabledElementName.style.display = 'none';
disabledElementName.style.display = 'block';
}
}
if (permissionToCheck) {
if (response.data[0][permissionToCheck] == 1) {
setAction("The '" + permissionToCheck + "' permission has been granted.", false);
setTimeout('clearAction();', 2000);
return true;
} else {
setAction('You need to grant the ' + permissionToCheck + ' permission before using this functionality.', false);
setTimeout('clearAction();', 2000);
} return false;
}
return true;
}
});
}

//Prompt the user to login and ask for the 'email' permission
function promptLogin() {
FB.login(null, {scope: 'email'});
}

//This will prompt the user to grant you acess to their Facebook Likes
function promptExtendedPermissions() {
FB.login(function() {
setAction("The 'user_likes' permission has been granted.", false);

setTimeout('clearAction();', 2000);

document.body.className = 'permissioned';
}, {scope: 'user_likes'});
//This will prompt the user to grant you acess to a given permission
function promptPermission(permission) {
FB.login(function(response) {
if (response.authResponse) {
checkUserPermissions(permission)
}
}, {scope: permission});
}

//See https://developers.facebook.com/docs/reference/rest/auth.revokeAuthorization/
//See https://developers.facebook.com/docs/reference/api/user/#permissions
function uninstallApp() {
FB.api({method: 'auth.revokeAuthorization'},
FB.api('/me/permissions', 'DELETE',
function(response) {
// window.location.reload();
// To clear the local storage cache and native session, call logout
logout();
});
//window.location.reload();
// For may instead call logout to clear
// cache data, ex: using in a PhoneGap app
logout();
});
}

//See https://developers.facebook.com/docs/reference/javascript/FB.logout/
Expand Down
42 changes: 4 additions & 38 deletions example/HackBook/js/graph_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,11 @@
//Detect when Facebook tells us that the user's session has been returned
function updateAuthElements() {
FB.Event.subscribe('auth.statusChange', function(session) {
//If the user isn't logged in, set the body class so that we show/hide the correct elements
if (!session.authResponse) {
if (document.body.className != 'not_connected') {
document.body.className = 'not_permissioned';
}
}
//The user is logged in, so let's see if they've granted the check-in permission and pre-fetch some data
//Depending on if they have or haven't, we'll set the body to reflect that so we show/hide the correct elements on the page
else {
if (session.authResponse) {
//The user is logged in, so let's pre-fetch some data and check the current
//permissions to show/hide the proper elements.
preFetchData();

FB.api({method: 'fql.query', query: 'SELECT user_checkins, publish_checkins FROM permissions WHERE uid = me()'}, function(response) {
if (document.body.className != 'not_connected') {
console.log("Reading permissions");
console.log(response);
//We couldn't get a check-in for the user, so they haven't granted the permission
if (response[0].user_checkins == 1) {
document.body.className = 'permissioned';
}
//We were able to get a check-in for the user, so they have granted the permission already
else {
document.body.className = 'not_permissioned';
}
}
});
checkUserPermissions();
}
});
}
Expand Down Expand Up @@ -179,20 +159,6 @@ function getNearby() {
});
}

//Prompt the user to grant the check-in permission
function promptCheckInPermission() {
FB.login(function(response) {
if (response.authResponse) {
//User granted permissions
document.body.className = 'permissioned';
}
else {
//User didn't grant permissions
alert('You need to grant the check-in permission before using this functionality.');
}
}, {scope:'user_checkins,publish_checkins'});
}

//Pre-fetch data, mainly used for requests and feed publish dialog
var nonAppFriendIDs = [];
var appFriendIDs = [];
Expand Down
Loading

0 comments on commit 881585f

Please sign in to comment.