Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*~ | ||
*.DS_Store | ||
*.class | ||
/facebook/bin/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="src" path="src"/> | ||
<classpathentry kind="lib" path="/Users/ssoneff/Downloads/android-sdk-mac_86/platforms/android-7/android.jar"/> | ||
This comment has been minimized.
Sorry, something went wrong. |
||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> | ||
<classpathentry kind="output" path="bin"/> | ||
</classpath> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>FacebookSDK</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
</natures> | ||
</projectDescription> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#Fri May 07 12:11:08 PDT 2010 | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 | ||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||
org.eclipse.jdt.core.compiler.compliance=1.6 | ||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | ||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | ||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | ||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||
org.eclipse.jdt.core.compiler.source=1.6 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
package com.facebook.android; | ||
|
||
import org.json.JSONException; | ||
import org.json.JSONObject; | ||
|
||
import android.app.ProgressDialog; | ||
import android.content.Context; | ||
import android.content.SharedPreferences; | ||
import android.os.Bundle; | ||
import android.os.Handler; | ||
import android.util.Log; | ||
|
||
import com.facebook.android.Util.Callback; | ||
|
||
// TODO(ssoneff): | ||
// make Facebook button | ||
// logout function? | ||
|
||
// size, title of uiActivity | ||
// support multiple facebook sessions? provide session manager? | ||
// wrapper for data: FacebookObject? | ||
// lower pri: auto uiInteraction on session failure? | ||
// request queue? request callbacks for loading, cancelled? | ||
|
||
// Questions: | ||
// fix fbconnect://... | ||
// oauth redirect not working | ||
// oauth does not return expires_in | ||
// expires_in is duration or expiration? | ||
// for errors: use string (message), error codes, or exceptions? | ||
// why callback on both receive response and loaded? | ||
// keep track of which permissions this session has? | ||
|
||
public class Facebook { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
public static final String SUCCESS_URI = "fbconnect://success"; | ||
public static final String PREFS_KEY = "facebook-session"; | ||
This comment has been minimized.
Sorry, something went wrong.
daaku
|
||
|
||
private static final String OAUTH_ENDPOINT = "http://graph.dev.facebook.com/oauth/authorize"; | ||
This comment has been minimized.
Sorry, something went wrong.
daaku
|
||
private static final String UI_SERVER = "http://www.facebook.com/connect/uiserver.php"; | ||
private static final String GRAPH_BASE_URL = "https://graph.facebook.com/"; | ||
private static final String RESTSERVER_URL = "http://api.facebook.com/restserver.php"; | ||
private static final String TOKEN = "oauth_token"; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
private Context mContext; | ||
private String mAppId; | ||
private String mAccessToken = null; | ||
private long mAccessExpires = 0; | ||
|
||
|
||
// Initialization | ||
|
||
public Facebook(Context c, String clientId) { | ||
this.mContext = c; | ||
this.mAppId = clientId; | ||
} | ||
|
||
public void login(DialogListener listener) { | ||
authorize(null, listener); | ||
} | ||
|
||
public void logout() { | ||
This comment has been minimized.
Sorry, something went wrong.
daaku
|
||
// TODO(ssoneff) how does logout work? de-auth api method?? | ||
// support multiple logout listeners? | ||
} | ||
|
||
public void authorize(String[] permissions, final DialogListener listener) { | ||
This comment has been minimized.
Sorry, something went wrong.
yariv
|
||
Bundle params = new Bundle(); | ||
params.putString("display", "touch"); | ||
This comment has been minimized.
Sorry, something went wrong.
daaku
|
||
params.putString("type", "user_agent"); | ||
params.putString("client_id", mAppId); | ||
params.putString("redirect_uri", SUCCESS_URI); | ||
if (permissions != null) params.putString("scope", Util.join(permissions, ',')); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
dialog("login", params, new DialogListener() { | ||
|
||
@Override | ||
public void onDialogSucceed(Bundle values) { | ||
String token = values.getString("access_token"); | ||
String expires = values.getString("expires_in"); | ||
Log.d("Facebook", "Success! access_token=" + token + " expires=" + expires); | ||
|
||
SharedPreferences s = mContext.getSharedPreferences(Facebook.PREFS_KEY, Context.MODE_PRIVATE); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
s.edit().putString("access_token", token); | ||
s.edit().putString("expires_in", expires); | ||
|
||
// WTF? commit does not work on emulator ... file system problem? | ||
if (s.edit().commit()) { | ||
Log.d("Facebook-WebView", "changes committed"); | ||
} else { | ||
Log.d("Facebook-WebView", "changes NOT committed"); | ||
} | ||
s = mContext.getSharedPreferences(Facebook.PREFS_KEY, Context.MODE_PRIVATE); | ||
Log.d("Facebook-Callback", "Stored: access_token=" + s.getString("access_token", "NONE")); | ||
|
||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
setAccessToken(token); | ||
setAccessExpiresIn(expires); | ||
listener.onDialogSucceed(values); | ||
} | ||
|
||
@Override | ||
public void onDialogFail(String error) { | ||
Log.d("Facebook-Callback", "Dialog failed: " + error); | ||
listener.onDialogFail(error); | ||
} | ||
|
||
@Override | ||
public void onDialogCancel() { | ||
Log.d("Facebook-Callback", "Dialog cancelled"); | ||
listener.onDialogCancel(); | ||
} | ||
}); | ||
} | ||
|
||
// API requests | ||
|
||
// support old API: method provided as parameter | ||
public void request(Bundle parameters, RequestListener listener) { | ||
request(null, "GET", parameters, listener); | ||
} | ||
|
||
public void request(String graphPath, RequestListener listener) { | ||
request(graphPath, "GET", new Bundle(), listener); | ||
} | ||
|
||
public void request(String graphPath, Bundle parameters, RequestListener listener) { | ||
request(graphPath, "GET", parameters, listener); | ||
} | ||
|
||
public void request(String graphPath, String httpMethod, Bundle parameters, final RequestListener listener) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
soneff
|
||
if (isSessionValid()) { parameters.putString(TOKEN, mAccessToken); } | ||
String url = graphPath != null ? GRAPH_BASE_URL + graphPath : RESTSERVER_URL; | ||
Util.asyncOpenUrl(url, httpMethod, Util.encodeUrl(parameters), new Callback() { | ||
This comment has been minimized.
Sorry, something went wrong.
daaku
|
||
public void call(String response) { | ||
try { | ||
JSONObject o = new JSONObject(response); | ||
if (o.has("error")) { | ||
listener.onRequestFail(o.getString("error")); | ||
} else { | ||
listener.onRequestSucceed(o); | ||
} | ||
} catch (JSONException e) { | ||
e.printStackTrace(); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
listener.onRequestFail(e.getMessage()); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
|
||
// UI Server requests | ||
|
||
public void dialog(String action, DialogListener listener) { | ||
dialog(action, null, listener); | ||
} | ||
|
||
public void dialog(String action, Bundle parameters, final DialogListener listener) { | ||
// need logic to determine correct endpoint for resource, e.g. "login" --> "oauth/authorize" | ||
String endpoint = action.equals("login") ? OAUTH_ENDPOINT : UI_SERVER; | ||
final String url = parameters == null ? endpoint + "?" + Util.encodeUrl(parameters) : endpoint; | ||
|
||
// This is buggy: webview dies with null pointer exception (but not in my code)... | ||
/* | ||
final ProgressDialog spinner = ProgressDialog.show(mContext, "Facebook", "Loading..."); | ||
final Handler h = new Handler(); | ||
// start async data fetch | ||
Util.asyncOpenUrl(url, "GET", Util.encodeUrl(parameters), new Callback() { | ||
@Override public void call(final String response) { | ||
Log.d("Facebook", "got response: " + response); | ||
if (response.length() == 0) listener.onDialogFail("Empty response"); | ||
h.post(new Runnable() { | ||
@Override public void run() { | ||
//callback: close progress dialog | ||
spinner.dismiss(); | ||
new FbDialog(mContext, url, response, listener).show(); | ||
} | ||
}); | ||
} | ||
}); | ||
*/ | ||
new FbDialog(mContext, url + "?" + Util.encodeUrl(parameters), "", listener).show(); | ||
} | ||
|
||
|
||
// utilities | ||
|
||
public boolean isSessionValid() { | ||
if (mAccessToken == null) { | ||
SharedPreferences store = mContext.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE); | ||
mAccessToken = store.getString("access_token", null); | ||
mAccessExpires = store.getLong("expires_in", 0); | ||
// throw not logged-in exception if no access token? need to call login() first | ||
} | ||
Log.d("Facebook SDK", "session valid? token=" + mAccessToken + " duration: " + -(System.currentTimeMillis() - mAccessExpires)); | ||
return mAccessToken != null && (mAccessExpires == 0 || System.currentTimeMillis() < mAccessExpires); | ||
} | ||
|
||
// get/set | ||
|
||
public String getAccessToken() { | ||
return mAccessToken; | ||
} | ||
|
||
public long getAccessExpires() { | ||
return mAccessExpires; | ||
} | ||
|
||
public void setAccessToken(String token) { | ||
mAccessToken = token; | ||
} | ||
|
||
public void setAccessExpiresIn(String expires_in) { | ||
if (expires_in != null) mAccessExpires = System.currentTimeMillis() + Integer.parseInt(expires_in)*1000; | ||
} | ||
|
||
|
||
// callback interfaces | ||
|
||
public static abstract class SessionLogoutListener { | ||
|
||
public void onSessionLogoutStart() { } | ||
|
||
public void onSessionLogoutFinish() { } | ||
} | ||
|
||
public static abstract class RequestListener { | ||
|
||
public abstract void onRequestSucceed(JSONObject response); | ||
|
||
public abstract void onRequestFail(String error); | ||
} | ||
|
||
public static abstract class DialogListener { | ||
|
||
public abstract void onDialogSucceed(Bundle values); | ||
|
||
public abstract void onDialogFail(String error); | ||
|
||
public void onDialogCancel() { } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.facebook.android; | ||
|
||
import android.content.Context; | ||
import android.widget.ImageButton; | ||
|
||
public class FbButton extends ImageButton { | ||
|
||
public FbButton(Context context) { | ||
super(context); | ||
// TODO Auto-generated constructor stub | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* | ||
*/ | ||
package com.facebook.android; | ||
|
||
import com.facebook.android.Facebook.DialogListener; | ||
|
||
import android.app.Dialog; | ||
import android.content.Context; | ||
import android.os.Bundle; | ||
import android.util.Log; | ||
import android.view.ViewGroup; | ||
import android.webkit.WebSettings; | ||
import android.webkit.WebView; | ||
import android.webkit.WebViewClient; | ||
import android.widget.FrameLayout.LayoutParams; | ||
|
||
public class FbDialog extends Dialog { | ||
|
||
private String mUrl; | ||
private String mData; | ||
private DialogListener mListener; | ||
private WebView mWebView; | ||
|
||
public FbDialog(Context context, String url, String data, DialogListener listener) { | ||
super(context); | ||
mUrl = url; | ||
mData = data; | ||
mListener = listener; | ||
} | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
initView(); | ||
} | ||
|
||
private void initView() { | ||
mWebView = new WebView(getContext()); | ||
mWebView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); | ||
mWebView.setWebViewClient(new FbDialog.FbWebViewClient()); | ||
WebSettings webSettings = mWebView.getSettings(); | ||
webSettings.setJavaScriptEnabled(true); | ||
//mWebView.loadDataWithBaseURL(mUrl, mData, "text/html", "UTF-8", null); // BUG: null pointer somewhere | ||
mWebView.loadUrl(mUrl); | ||
|
||
// extract title and size from data | ||
addContentView(mWebView, new LayoutParams(280, 360)); | ||
setTitle("Facebook Rulz"); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
soneff
|
||
} | ||
|
||
@Override | ||
public void onBackPressed() { | ||
super.onBackPressed(); | ||
mListener.onDialogCancel(); | ||
} | ||
|
||
private class FbWebViewClient extends WebViewClient { | ||
|
||
@Override | ||
public boolean shouldOverrideUrlLoading(WebView view, String url) { | ||
Log.d("Facebook-WebView", "Webview loading URL: " + url); | ||
if (url.startsWith(Facebook.SUCCESS_URI)) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
mListener.onDialogSucceed(Util.parseUrl(url)); | ||
FbDialog.this.dismiss(); | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public void onPageFinished(WebView view, String url) { | ||
super.onPageFinished(view, url); | ||
Log.d("Facebook-WebView", "Loaded URL: " + url); | ||
// HACK HACK HACK: oauth needs to be fixed on server-side | ||
if (url.contains("auth_token=")) { | ||
mListener.onDialogSucceed(Util.parseUrl("http://success/#access_token=110862205611506%7Ce54333664a458cabe3ed8e3f-648474582%7CvcpLpG7BNiLF1QAyZgydkfQEBQU.")); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
FbDialog.this.dismiss(); | ||
} | ||
} | ||
} | ||
|
||
} |
should remove this and the line underneath