Android
Tuesday, 19 May 2015
Thursday, 7 June 2012
Send e-mail using the JavaMail API using Gmail authentication in Android
First you have to download three jar files.
1. mail.jar
- Then Right Click on your project,Select Build Path. From that select Configure Build Path.
- Then in Libraries Tab select Add External Jars and then select the path where you downloaded jar files.
- Add all the three jar files and click ok.
AutomaticMailActivity.class
package com.mail;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class AutomaticMailActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
GMailSender sender = new GMailSender("xxxxxxxxxxxx@gmail.com", "xxxxxxxx");
sender.sendMail("This is Subject",
"This is Body",
" xxxxxxxxxxxx@gmail.com "," xxxxxxxxxxxx@gmail.com ");
} catch (Exception e) {
Log.e("SendMail", e.getMessage(), e);
}
}
}
GMailSender.class
package com.mail;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import java.util.Properties;
public class GMailSender extends javax.mail.Authenticator {
private String mailhost = "smtp.gmail.com";
private String user;
private String password;
private Session session;
static {
Security.addProvider(new com.provider.JSSEProvider());
}
public GMailSender(String user, String password) {
this.user = user;
this.password = password;
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", mailhost);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
session = Session.getDefaultInstance(props, this);
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception {
try{
MimeMessage message = new MimeMessage(session);
DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));
message.setSender(new InternetAddress(sender));
message.setSubject(subject);
message.setDataHandler(handler);
if (recipients.indexOf(',') > 0)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
else
message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
Transport.send(message);
}catch(Exception e){
}
}
public class ByteArrayDataSource implements DataSource {
private byte[] data;
private String type;
public ByteArrayDataSource(byte[] data, String type) {
super();
this.data = data;
this.type = type;
}
public ByteArrayDataSource(byte[] data) {
super();
this.data = data;
}
public void setType(String type) {
this.type = type;
}
public String getContentType() {
if (type == null)
return "application/octet-stream";
else
return type;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data);
}
public String getName() {
return "ByteArrayDataSource";
}
public OutputStream getOutputStream() throws IOException {
throw new IOException("Not Supported");
}
}
}
JSSEProvider.class
package com.provider;
import java.security.AccessController;
import java.security.Provider;
public final class JSSEProvider extends Provider {
public JSSEProvider() {
super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
public Void run() {
put("SSLContext.TLS",
"org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
put("Alg.Alias.SSLContext.TLSv1", "TLS");
put("KeyManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
put("TrustManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
return null;
}
});
}
}
main.xml
No need to add anything here .leave the default one.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mail"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".AutomaticMailActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>"
</manifest>
Tuesday, 5 June 2012
Facebook Integration in Android
First you have to register your app in https://developers.facebook.com/ and get app Id
Login.class
package com.kmiller.facebookintegration;
import org.json.JSONObject;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.FacebookError;
import com.facebook.android.Facebook.DialogListener;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Login extends Activity {
public static final String mAPP_ID = "<your_app_id_here>";
public Facebook mFacebook = new Facebook(mAPP_ID);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button)findViewById(R.id.LoginButton)).setOnClickListener( loginButtonListener );
SessionStore.restore(mFacebook, this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mFacebook.authorizeCallback(requestCode, resultCode, data);
}
private OnClickListener loginButtonListener = new OnClickListener() {
public void onClick( View v ) {
if( !mFacebook.isSessionValid() ) {
Toast.makeText(Login.this, "Authorizing", Toast.LENGTH_SHORT).show();
mFacebook.authorize(Login.this, new String[] { "" }, new LoginDialogListener());
}
else {
Toast.makeText( Login.this, "Has valid session", Toast.LENGTH_SHORT).show();
try {
JSONObject json = Util.parseJson(mFacebook.request("me"));
String facebookID = json.getString("id");
String firstName = json.getString("first_name");
String lastName = json.getString("last_name");
Toast.makeText(Login.this, "You already have a valid session, " + firstName + " " + lastName + ". No need to re-authorize.", Toast.LENGTH_SHORT).show();
}
catch( Exception error ) {
Toast.makeText( Login.this, error.toString(), Toast.LENGTH_SHORT).show();
}
catch( FacebookError error ) {
Toast.makeText( Login.this, error.toString(), Toast.LENGTH_SHORT).show();
}
}
}
};
public final class LoginDialogListener implements DialogListener {
public void onComplete(Bundle values) {
try {
JSONObject json = Util.parseJson(mFacebook.request("me"));
String facebookID = json.getString("id");
String firstName = json.getString("first_name");
String lastName = json.getString("last_name");
Toast.makeText( Login.this, "Thank you for Logging In, " + firstName + " " + lastName + "!", Toast.LENGTH_SHORT).show();
SessionStore.save(mFacebook, Login.this);
}
catch( Exception error ) {
Toast.makeText( Login.this, error.toString(), Toast.LENGTH_SHORT).show();
}
catch( FacebookError error ) {
Toast.makeText( Login.this, error.toString(), Toast.LENGTH_SHORT).show();
}
}
public void onFacebookError(FacebookError error) {
Toast.makeText( Login.this, "Something went wrong. Please try again.", Toast.LENGTH_LONG).show();
}
public void onError(DialogError error) {
Toast.makeText( Login.this, "Something went wrong. Please try again.", Toast.LENGTH_LONG).show();
}
public void onCancel() {
Toast.makeText( Login.this, "Something went wrong. Please try again.", Toast.LENGTH_LONG).show();
}
}
}
SessionStore.class
package com.kmiller.facebookintegration;
import com.facebook.android.Facebook;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class SessionStore {
private static final String TOKEN = "access_token";
private static final String EXPIRES = "expires_in";
private static final String KEY = "facebook-session";
public static boolean save(Facebook session, Context context) {
Editor editor =
context.getSharedPreferences(KEY, Context.MODE_PRIVATE).edit();
editor.putString(TOKEN, session.getAccessToken());
editor.putLong(EXPIRES, session.getAccessExpires());
return editor.commit();
}
public static boolean restore(Facebook session, Context context) {
SharedPreferences savedSession =
context.getSharedPreferences(KEY, Context.MODE_PRIVATE);
session.setAccessToken(savedSession.getString(TOKEN, null));
session.setAccessExpires(savedSession.getLong(EXPIRES, 0));
return session.isSessionValid();
}
public static void clear(Context context) {
Editor editor =
context.getSharedPreferences(KEY, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
}
}
Util.class
package com.kmiller.facebookintegration;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import org.json.JSONException;
import org.json.JSONObject;
import com.facebook.android.FacebookError;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
public final class Util {
public static String encodePostBody(Bundle parameters, String boundary) {
if (parameters == null) return "";
StringBuilder sb = new StringBuilder();
for (String key : parameters.keySet()) {
if (parameters.getByteArray(key) != null) {
continue;
}
sb.append("Content-Disposition: form-data; name=\"" + key +
"\"\r\n\r\n" + parameters.getString(key));
sb.append("\r\n" + "--" + boundary + "\r\n");
}
return sb.toString();
}
public static String encodeUrl(Bundle parameters) {
if (parameters == null) {
return "";
}
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String key : parameters.keySet()) {
if (first) first = false; else sb.append("&");
sb.append(URLEncoder.encode(key) + "=" +
URLEncoder.encode(parameters.getString(key)));
}
return sb.toString();
}
public static Bundle decodeUrl(String s) {
Bundle params = new Bundle();
if (s != null) {
String array[] = s.split("&");
for (String parameter : array) {
String v[] = parameter.split("=");
params.putString(URLDecoder.decode(v[0]),
URLDecoder.decode(v[1]));
}
}
return params;
}
public static Bundle parseUrl(String url) {
url = url.replace("fbconnect", "http");
try {
URL u = new URL(url);
Bundle b = decodeUrl(u.getQuery());
b.putAll(decodeUrl(u.getRef()));
return b;
} catch (MalformedURLException e) {
return new Bundle();
}
}
public static String openUrl(String url, String method, Bundle params)
throws MalformedURLException, IOException {
String strBoundary = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
String endLine = "\r\n";
OutputStream os;
if (method.equals("GET")) {
url = url + "?" + encodeUrl(params);
}
Log.d("Facebook-Util", method + " URL: " + url);
HttpURLConnection conn =
(HttpURLConnection) new URL(url).openConnection();
conn.setRequestProperty("User-Agent", System.getProperties().
getProperty("http.agent") + " FacebookAndroidSDK");
if (!method.equals("GET")) {
Bundle dataparams = new Bundle();
for (String key : params.keySet()) {
if (params.getByteArray(key) != null) {
dataparams.putByteArray(key, params.getByteArray(key));
}
}
if (!params.containsKey("method")) {
params.putString("method", method);
}
if (params.containsKey("access_token")) {
String decoded_token =
URLDecoder.decode(params.getString("access_token"));
params.putString("access_token", decoded_token);
}
conn.setRequestMethod("POST");
conn.setRequestProperty(
"Content-Type",
"multipart/form-data;boundary="+strBoundary);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
os = new BufferedOutputStream(conn.getOutputStream());
os.write(("--" + strBoundary +endLine).getBytes());
os.write((encodePostBody(params, strBoundary)).getBytes());
os.write((endLine + "--" + strBoundary + endLine).getBytes());
if (!dataparams.isEmpty()) {
for (String key: dataparams.keySet()){
os.write(("Content-Disposition: form-data; filename=\"" + key + "\"" + endLine).getBytes());
os.write(("Content-Type: content/unknown" + endLine + endLine).getBytes());
os.write(dataparams.getByteArray(key));
os.write((endLine + "--" + strBoundary + endLine).getBytes());
}
}
os.flush();
}
String response = "";
try {
response = read(conn.getInputStream());
} catch (FileNotFoundException e) {
response = read(conn.getErrorStream());
}
return response;
}
private static String read(InputStream in) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
}
in.close();
return sb.toString();
}
public static void clearCookies(Context context) {
@SuppressWarnings("unused")
CookieSyncManager cookieSyncMngr =
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
}
public static JSONObject parseJson(String response)
throws JSONException, FacebookError {
if (response.equals("false")) {
throw new FacebookError("request failed");
}
if (response.equals("true")) {
response = "{value : true}";
}
JSONObject json = new JSONObject(response);
if (json.has("error")) {
JSONObject error = json.getJSONObject("error");
throw new FacebookError(
error.getString("message"), error.getString("type"), 0);
}
if (json.has("error_code") && json.has("error_msg")) {
throw new FacebookError(json.getString("error_msg"), "",
Integer.parseInt(json.getString("error_code")));
}
if (json.has("error_code")) {
throw new FacebookError("request failed", "",
Integer.parseInt(json.getString("error_code")));
}
if (json.has("error_msg")) {
throw new FacebookError(json.getString("error_msg"));
}
if (json.has("error_reason")) {
throw new FacebookError(json.getString("error_reason"));
}
return json;
}
public static void showAlert(Context context, String title, String text) {
Builder alertBuilder = new Builder(context);
alertBuilder.setTitle(title);
alertBuilder.setMessage(text);
alertBuilder.create().show();
}
}
AsyncFacebookRunner .class
package com.facebook.android;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import android.content.Context;
import android.os.Bundle;
public class AsyncFacebookRunner {
Facebook fb;
public AsyncFacebookRunner(Facebook fb) {
this.fb = fb;
}
public void logout(final Context context, final RequestListener listener) {
new Thread() {
@Override public void run() {
try {
String response = fb.logout(context);
if (response.length() == 0 || response.equals("false")){
listener.onFacebookError(new FacebookError(
"auth.expireSession failed"));
return;
}
listener.onComplete(response);
} catch (FileNotFoundException e) {
listener.onFileNotFoundException(e);
} catch (MalformedURLException e) {
listener.onMalformedURLException(e);
} catch (IOException e) {
listener.onIOException(e);
}
}
}.start();
}
public void request(Bundle parameters,
RequestListener listener) {
request(null, parameters, "GET", listener);
}
public void request(String graphPath,
RequestListener listener) {
request(graphPath, new Bundle(), "GET", listener);
}
public void request(String graphPath,
Bundle parameters,
RequestListener listener) {
request(graphPath, parameters, "GET", listener);
}
public void request(final String graphPath,
final Bundle parameters,
final String httpMethod,
final RequestListener listener) {
new Thread() {
@Override public void run() {
try {
String resp = fb.request(graphPath, parameters, httpMethod);
listener.onComplete(resp);
} catch (FileNotFoundException e) {
listener.onFileNotFoundException(e);
} catch (MalformedURLException e) {
listener.onMalformedURLException(e);
} catch (IOException e) {
listener.onIOException(e);
}
}
}.start();
}
public static interface RequestListener {
public void onComplete(String response);
public void onIOException(IOException e);
public void onFileNotFoundException(FileNotFoundException e);
public void onMalformedURLException(MalformedURLException e);
public void onFacebookError(FacebookError e);
}
}
DialogError.class
package com.facebook.android;
public class DialogError extends Throwable {
private static final long serialVersionUID = 1L;
private int mErrorCode;
private String mFailingUrl;
public DialogError(String message, int errorCode, String failingUrl) {
super(message);
mErrorCode = errorCode;
mFailingUrl = failingUrl;
}
int getErrorCode() {
return mErrorCode;
}
String getFailingUrl() {
return mFailingUrl;
}
}
Facebook.class
package com.facebook.android;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.CookieSyncManager;
public class Facebook {
public static final String REDIRECT_URI = "fbconnect://success";
public static final String CANCEL_URI = "fbconnect://cancel";
public static final String TOKEN = "access_token";
public static final String EXPIRES = "expires_in";
public static final String SINGLE_SIGN_ON_DISABLED = "service_disabled";
public static final int FORCE_DIALOG_AUTH = -1;
private static final String LOGIN = "oauth";
private static final int DEFAULT_AUTH_ACTIVITY_CODE = 32665;
protected static String DIALOG_BASE_URL =
"https://m.facebook.com/dialog/";
protected static String GRAPH_BASE_URL =
"https://graph.facebook.com/";
protected static String RESTSERVER_URL =
"https://api.facebook.com/restserver.php";
private String mAccessToken = null;
private long mAccessExpires = 0;
private String mAppId;
private Activity mAuthActivity;
private String[] mAuthPermissions;
private int mAuthActivityCode;
private DialogListener mAuthDialogListener;
public Facebook(String appId) {
if (appId == null) {
throw new IllegalArgumentException(
"You must specify your application ID when instantiating " +
"a Facebook object. See README for details.");
}
mAppId = appId;
}
public void authorize(Activity activity, final DialogListener listener) {
authorize(activity, new String[] {}, DEFAULT_AUTH_ACTIVITY_CODE,
listener);
}
public void authorize(Activity activity, String[] permissions,
final DialogListener listener) {
authorize(activity, permissions, DEFAULT_AUTH_ACTIVITY_CODE, listener);
}
public void authorize(Activity activity, String[] permissions,
int activityCode, final DialogListener listener) {
boolean singleSignOnStarted = false;
mAuthDialogListener = listener;
if (activityCode >= 0) {
singleSignOnStarted = startSingleSignOn(activity, mAppId,
permissions, activityCode);
}
if (!singleSignOnStarted) {
startDialogAuth(activity, permissions);
}
}
private boolean startSingleSignOn(Activity activity, String applicationId,
String[] permissions, int activityCode) {
boolean didSucceed = true;
Intent intent = new Intent();
intent.setClassName("com.facebook.katana",
"com.facebook.katana.ProxyAuth");
intent.putExtra("client_id", applicationId);
if (permissions.length > 0) {
intent.putExtra("scope", TextUtils.join(",", permissions));
}
if (!validateAppSignatureForIntent(activity, intent)) {
return false;
}
mAuthActivity = activity;
mAuthPermissions = permissions;
mAuthActivityCode = activityCode;
try {
activity.startActivityForResult(intent, activityCode);
} catch (ActivityNotFoundException e) {
didSucceed = false;
}
return didSucceed;
}
private boolean validateAppSignatureForIntent(Activity activity,
Intent intent) {
ResolveInfo resolveInfo =
activity.getPackageManager().resolveActivity(intent, 0);
if (resolveInfo == null) {
return false;
}
String packageName = resolveInfo.activityInfo.packageName;
PackageInfo packageInfo;
try {
packageInfo = activity.getPackageManager().getPackageInfo(
packageName, PackageManager.GET_SIGNATURES);
} catch (NameNotFoundException e) {
return false;
}
for (Signature signature : packageInfo.signatures) {
if (signature.toCharsString().equals(FB_APP_SIGNATURE)) {
return true;
}
}
return false;
}
private void startDialogAuth(Activity activity, String[] permissions) {
Bundle params = new Bundle();
if (permissions.length > 0) {
params.putString("scope", TextUtils.join(",", permissions));
}
CookieSyncManager.createInstance(activity);
dialog(activity, LOGIN, params, new DialogListener() {
public void onComplete(Bundle values) {
CookieSyncManager.getInstance().sync();
setAccessToken(values.getString(TOKEN));
setAccessExpiresIn(values.getString(EXPIRES));
if (isSessionValid()) {
Log.d("Facebook-authorize", "Login Success! access_token="
+ getAccessToken() + " expires="
+ getAccessExpires());
mAuthDialogListener.onComplete(values);
} else {
mAuthDialogListener.onFacebookError(new FacebookError(
"Failed to receive access token."));
}
}
public void onError(DialogError error) {
Log.d("Facebook-authorize", "Login failed: " + error);
mAuthDialogListener.onError(error);
}
public void onFacebookError(FacebookError error) {
Log.d("Facebook-authorize", "Login failed: " + error);
mAuthDialogListener.onFacebookError(error);
}
public void onCancel() {
Log.d("Facebook-authorize", "Login canceled");
mAuthDialogListener.onCancel();
}
});
}
public void authorizeCallback(int requestCode, int resultCode, Intent data) {
if (requestCode == mAuthActivityCode) {
if (resultCode == Activity.RESULT_OK) {
String error = data.getStringExtra("error");
if (error == null) {
error = data.getStringExtra("error_type");
}
if (error != null) {
if (error.equals(SINGLE_SIGN_ON_DISABLED)
|| error.equals("AndroidAuthKillSwitchException")) {
Log.d("Facebook-authorize", "Hosted auth currently "
+ "disabled. Retrying dialog auth...");
startDialogAuth(mAuthActivity, mAuthPermissions);
} else if (error.equals("access_denied")
|| error.equals("OAuthAccessDeniedException")) {
Log.d("Facebook-authorize", "Login canceled by user.");
mAuthDialogListener.onCancel();
} else {
Log.d("Facebook-authorize", "Login failed: " + error);
mAuthDialogListener.onFacebookError(
new FacebookError(error));
}
} else {
setAccessToken(data.getStringExtra(TOKEN));
setAccessExpiresIn(data.getStringExtra(EXPIRES));
if (isSessionValid()) {
Log.d("Facebook-authorize",
"Login Success! access_token="
+ getAccessToken() + " expires="
+ getAccessExpires());
mAuthDialogListener.onComplete(data.getExtras());
} else {
mAuthDialogListener.onFacebookError(new FacebookError(
"Failed to receive access token."));
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
if (data != null) {
Log.d("Facebook-authorize",
"Login failed: " + data.getStringExtra("error"));
mAuthDialogListener.onError(
new DialogError(
data.getStringExtra("error"),
data.getIntExtra("error_code", -1),
data.getStringExtra("failing_url")));
} else {
Log.d("Facebook-authorize", "Login canceled by user.");
mAuthDialogListener.onCancel();
}
}
}
}
public String logout(Context context)
throws MalformedURLException, IOException {
Util.clearCookies(context);
Bundle b = new Bundle();
b.putString("method", "auth.expireSession");
String response = request(b);
setAccessToken(null);
setAccessExpires(0);
return response;
}
public String request(Bundle parameters)
throws MalformedURLException, IOException {
if (!parameters.containsKey("method")) {
throw new IllegalArgumentException("API method must be specified. "
+ "(parameters must contain key \"method\" and value). See"
+ " http://developers.facebook.com/docs/reference/rest/");
}
return request(null, parameters, "GET");
}
public String request(String graphPath)
throws MalformedURLException, IOException {
return request(graphPath, new Bundle(), "GET");
}
public String request(String graphPath, Bundle parameters)
throws MalformedURLException, IOException {
return request(graphPath, parameters, "GET");
}
public String request(String graphPath, Bundle params, String httpMethod)
throws FileNotFoundException, MalformedURLException, IOException {
params.putString("format", "json");
if (isSessionValid()) {
params.putString(TOKEN, getAccessToken());
}
String url = (graphPath != null) ? GRAPH_BASE_URL + graphPath
: RESTSERVER_URL;
return Util.openUrl(url, httpMethod, params);
}
public void dialog(Context context, String action,
DialogListener listener) {
dialog(context, action, new Bundle(), listener);
}
public void dialog(Context context, String action, Bundle parameters,
final DialogListener listener) {
String endpoint = DIALOG_BASE_URL + action;
parameters.putString("display", "touch");
parameters.putString("redirect_uri", REDIRECT_URI);
if (action.equals(LOGIN)) {
parameters.putString("type", "user_agent");
parameters.putString("client_id", mAppId);
} else {
parameters.putString("app_id", mAppId);
}
if (isSessionValid()) {
parameters.putString(TOKEN, getAccessToken());
}
String url = endpoint + "?" + Util.encodeUrl(parameters);
if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET)
!= PackageManager.PERMISSION_GRANTED) {
Util.showAlert(context, "Error",
"Application requires permission to access the Internet");
} else {
new FbDialog(context, url, listener).show();
}
}
public boolean isSessionValid() {
return (getAccessToken() != null) &&
((getAccessExpires() == 0) ||
(System.currentTimeMillis() < getAccessExpires()));
}
public String getAccessToken() {
return mAccessToken;
}
public long getAccessExpires() {
return mAccessExpires;
}
public void setAccessToken(String token) {
mAccessToken = token;
}
public void setAccessExpires(long time) {
mAccessExpires = time;
}
public void setAccessExpiresIn(String expiresIn) {
if (expiresIn != null && !expiresIn.equals("0")) {
setAccessExpires(System.currentTimeMillis()
+ Integer.parseInt(expiresIn) * 1000);
}
}
public String getAppId() {
return mAppId;
}
public void setAppId(String appId) {
mAppId = appId;
}
public static interface DialogListener {
public void onComplete(Bundle values);
public void onFacebookError(FacebookError e);
public void onError(DialogError e);
public void onCancel();
}
public static final String FB_APP_SIGNATURE =
"30820268308201d102044a9c4610300d06092a864886f70d0101040500307a310"
+ "b3009060355040613025553310b30090603550408130243413112301006035504"
+ "07130950616c6f20416c746f31183016060355040a130f46616365626f6f6b204"
+ "d6f62696c653111300f060355040b130846616365626f6f6b311d301b06035504"
+ "03131446616365626f6f6b20436f72706f726174696f6e3020170d30393038333"
+ "13231353231365a180f32303530303932353231353231365a307a310b30090603"
+ "55040613025553310b30090603550408130243413112301006035504071309506"
+ "16c6f20416c746f31183016060355040a130f46616365626f6f6b204d6f62696c"
+ "653111300f060355040b130846616365626f6f6b311d301b06035504031314466"
+ "16365626f6f6b20436f72706f726174696f6e30819f300d06092a864886f70d01"
+ "0101050003818d0030818902818100c207d51df8eb8c97d93ba0c8c1002c928fa"
+ "b00dc1b42fca5e66e99cc3023ed2d214d822bc59e8e35ddcf5f44c7ae8ade50d7"
+ "e0c434f500e6c131f4a2834f987fc46406115de2018ebbb0d5a3c261bd97581cc"
+ "fef76afc7135a6d59e8855ecd7eacc8f8737e794c60a761c536b72b11fac8e603"
+ "f5da1a2d54aa103b8a13c0dbc10203010001300d06092a864886f70d010104050"
+ "0038181005ee9be8bcbb250648d3b741290a82a1c9dc2e76a0af2f2228f1d9f9c"
+ "4007529c446a70175c5a900d5141812866db46be6559e2141616483998211f4a6"
+ "73149fb2232a10d247663b26a9031e15f84bc1c74d141ff98a02d76f85b2c8ab2"
+ "571b6469b232d8e768a7f7ca04f7abe4a775615916c07940656b58717457b42bd"
+ "928a2";
}
FacebookError.class
package com.facebook.android;
public class FacebookError extends Throwable {
private static final long serialVersionUID = 1L;
private int mErrorCode = 0;
private String mErrorType;
public FacebookError(String message) {
super(message);
}
public FacebookError(String message, String type, int code) {
super(message);
mErrorType = type;
mErrorCode = code;
}
public int getErrorCode() {
return mErrorCode;
}
public String getErrorType() {
return mErrorType;
}
}
FbDialog.class
package com.facebook.android;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.kmiller.facebookintegration.R;
import com.facebook.android.Facebook.DialogListener;
public class FbDialog extends Dialog {
static final int FB_BLUE = 0xFF6D84B4;
static final float[] DIMENSIONS_LANDSCAPE = {460, 260};
static final float[] DIMENSIONS_PORTRAIT = {280, 420};
static final FrameLayout.LayoutParams FILL =
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
static final int MARGIN = 4;
static final int PADDING = 2;
static final String DISPLAY_STRING = "touch";
static final String FB_ICON = "icon.png";
private String mUrl;
private DialogListener mListener;
private ProgressDialog mSpinner;
private WebView mWebView;
private LinearLayout mContent;
private TextView mTitle;
public FbDialog(Context context, String url, DialogListener listener) {
super(context);
mUrl = url;
mListener = listener;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSpinner = new ProgressDialog(getContext());
mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
mSpinner.setMessage("Loading...");
mContent = new LinearLayout(getContext());
mContent.setOrientation(LinearLayout.VERTICAL);
setUpTitle();
setUpWebView();
Display display = getWindow().getWindowManager().getDefaultDisplay();
final float scale = getContext().getResources().getDisplayMetrics().density;
float[] dimensions =
(display.getWidth() < display.getHeight())
? DIMENSIONS_PORTRAIT : DIMENSIONS_LANDSCAPE;
addContentView(mContent, new FrameLayout.LayoutParams(
(int) (dimensions[0] * scale + 0.5f),
(int) (dimensions[1] * scale + 0.5f)));
}
private void setUpTitle() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
Drawable icon = getContext().getResources().getDrawable(
R.drawable.facebook_icon);
mTitle = new TextView(getContext());
mTitle.setText("Facebook");
mTitle.setTextColor(Color.WHITE);
mTitle.setTypeface(Typeface.DEFAULT_BOLD);
mTitle.setBackgroundColor(FB_BLUE);
mTitle.setPadding(MARGIN + PADDING, MARGIN, MARGIN, MARGIN);
mTitle.setCompoundDrawablePadding(MARGIN + PADDING);
mTitle.setCompoundDrawablesWithIntrinsicBounds(
icon, null, null, null);
mContent.addView(mTitle);
}
private void setUpWebView() {
mWebView = new WebView(getContext());
mWebView.setVerticalScrollBarEnabled(false);
mWebView.setHorizontalScrollBarEnabled(false);
mWebView.setWebViewClient(new FbDialog.FbWebViewClient());
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl(mUrl);
mWebView.setLayoutParams(FILL);
mContent.addView(mWebView);
}
private class FbWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.d("Facebook-WebView", "Redirect URL: " + url);
if (url.startsWith(Facebook.REDIRECT_URI)) {
Bundle values = Util.parseUrl(url);
String error = values.getString("error");
if (error == null) {
error = values.getString("error_type");
}
if (error == null) {
mListener.onComplete(values);
} else if (error.equals("access_denied") ||
error.equals("OAuthAccessDeniedException")) {
mListener.onCancel();
} else {
mListener.onFacebookError(new FacebookError(error));
}
FbDialog.this.dismiss();
return true;
} else if (url.startsWith(Facebook.CANCEL_URI)) {
mListener.onCancel();
FbDialog.this.dismiss();
return true;
} else if (url.contains(DISPLAY_STRING)) {
return false;
}
getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
}
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
mListener.onError(
new DialogError(description, errorCode, failingUrl));
FbDialog.this.dismiss();
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.d("Facebook-WebView", "Webview loading URL: " + url);
super.onPageStarted(view, url, favicon);
mSpinner.show();
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String title = mWebView.getTitle();
if (title != null && title.length() > 0) {
mTitle.setText(title);
}
mSpinner.dismiss();
}
}
}
Util.class
package com.facebook.android;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
public final class Util {
public static String encodePostBody(Bundle parameters, String boundary) {
if (parameters == null) return "";
StringBuilder sb = new StringBuilder();
for (String key : parameters.keySet()) {
if (parameters.getByteArray(key) != null) {
continue;
}
sb.append("Content-Disposition: form-data; name=\"" + key +
"\"\r\n\r\n" + parameters.getString(key));
sb.append("\r\n" + "--" + boundary + "\r\n");
}
return sb.toString();
}
public static String encodeUrl(Bundle parameters) {
if (parameters == null) {
return "";
}
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String key : parameters.keySet()) {
if (first) first = false; else sb.append("&");
sb.append(URLEncoder.encode(key) + "=" +
URLEncoder.encode(parameters.getString(key)));
}
return sb.toString();
}
public static Bundle decodeUrl(String s) {
Bundle params = new Bundle();
if (s != null) {
String array[] = s.split("&");
for (String parameter : array) {
String v[] = parameter.split("=");
params.putString(URLDecoder.decode(v[0]),
URLDecoder.decode(v[1]));
}
}
return params;
}
public static Bundle parseUrl(String url) {
// hack to prevent MalformedURLException
url = url.replace("fbconnect", "http");
try {
URL u = new URL(url);
Bundle b = decodeUrl(u.getQuery());
b.putAll(decodeUrl(u.getRef()));
return b;
} catch (MalformedURLException e) {
return new Bundle();
}
}
public static String openUrl(String url, String method, Bundle params)
throws MalformedURLException, IOException {
String strBoundary = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
String endLine = "\r\n";
OutputStream os;
if (method.equals("GET")) {
url = url + "?" + encodeUrl(params);
}
Log.d("Facebook-Util", method + " URL: " + url);
HttpURLConnection conn =
(HttpURLConnection) new URL(url).openConnection();
conn.setRequestProperty("User-Agent", System.getProperties().
getProperty("http.agent") + " FacebookAndroidSDK");
if (!method.equals("GET")) {
Bundle dataparams = new Bundle();
for (String key : params.keySet()) {
if (params.getByteArray(key) != null) {
dataparams.putByteArray(key, params.getByteArray(key));
}
}
if (!params.containsKey("method")) {
params.putString("method", method);
}
if (params.containsKey("access_token")) {
String decoded_token =
URLDecoder.decode(params.getString("access_token"));
params.putString("access_token", decoded_token);
}
conn.setRequestMethod("POST");
conn.setRequestProperty(
"Content-Type",
"multipart/form-data;boundary="+strBoundary);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
os = new BufferedOutputStream(conn.getOutputStream());
os.write(("--" + strBoundary +endLine).getBytes());
os.write((encodePostBody(params, strBoundary)).getBytes());
os.write((endLine + "--" + strBoundary + endLine).getBytes());
if (!dataparams.isEmpty()) {
for (String key: dataparams.keySet()){
os.write(("Content-Disposition: form-data; filename=\"" + key + "\"" + endLine).getBytes());
os.write(("Content-Type: content/unknown" + endLine + endLine).getBytes());
os.write(dataparams.getByteArray(key));
os.write((endLine + "--" + strBoundary + endLine).getBytes());
}
}
os.flush();
}
String response = "";
try {
response = read(conn.getInputStream());
} catch (FileNotFoundException e) {
response = read(conn.getErrorStream());
}
return response;
}
private static String read(InputStream in) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
}
in.close();
return sb.toString();
}
public static void clearCookies(Context context) {
@SuppressWarnings("unused")
CookieSyncManager cookieSyncMngr =
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
}
public static JSONObject parseJson(String response)
throws JSONException, FacebookError {
// Edge case: when sending a POST request to /[post_id]/likes
// the return value is 'true' or 'false'. Unfortunately
// these values cause the JSONObject constructor to throw
// an exception.
if (response.equals("false")) {
throw new FacebookError("request failed");
}
if (response.equals("true")) {
response = "{value : true}";
}
JSONObject json = new JSONObject(response);
if (json.has("error")) {
JSONObject error = json.getJSONObject("error");
throw new FacebookError(
error.getString("message"), error.getString("type"), 0);
}
if (json.has("error_code") && json.has("error_msg")) {
throw new FacebookError(json.getString("error_msg"), "",
Integer.parseInt(json.getString("error_code")));
}
if (json.has("error_code")) {
throw new FacebookError("request failed", "",
Integer.parseInt(json.getString("error_code")));
}
if (json.has("error_msg")) {
throw new FacebookError(json.getString("error_msg"));
}
if (json.has("error_reason")) {
throw new FacebookError(json.getString("error_reason"));
}
return json;
}
public static void showAlert(Context context, String title, String text) {
Builder alertBuilder = new Builder(context);
alertBuilder.setTitle(title);
alertBuilder.setMessage(text);
alertBuilder.create().show();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="20dip"
android:gravity="center_horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Facebook Integration Demo"
android:textStyle="bold"
android:textSize="24dip"
android:textColor="#ffffff"
android:layout_marginBottom="20dip"
android:gravity="center" >
</TextView>
<Button android:id="@+id/LoginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Login to Facebook" >
</Button>
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kmiller.facebookintegration"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Login"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Subscribe to:
Posts (Atom)