The framework contains two way of login sequences, one is Single Sign-On(SSO) and the other is dialogs with WebView.
Both are so useful and are enabled by default (SSO have first priority. If end users have already installed Facebook app, the SSO sequence will start).
However, from implementing point of view, there are some difficulties. The difficulties is that authorization result is not constant.
The following introduce how I dealt with the results from both SSO and WebView.
The main problem is that the framework always returns RESULT_OK to my onActivityResult method.
But callback methods specified in Facebook#authorize receive actual status after the calling of onActivity method.
So I arranged to wait for moment after onActivityResult calling.
public class FacebookDialogActivity extends Activity {
private Context mContext;
private Facebook mFb;
private final static String APP_ID = "YOUR APP ID";
private final static int INTENT_CODE_FB_DIALOG = 0x04;
private final static int DIALOG_ID_WAITING_FOR_ERROR = 0xD01;
private ProgressDialog mProcessingResultDialog;
/** to return back the authorization result to my activity, which called startActivityForResult method */
private int mResultCode = Activity.RESULT_OK;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mContext = getApplicationContext();
mFb = new Facebook(APP_ID);
mFb.authorize(this, new String[]{},
INTENT_CODE_FB_DIALOG,
new com.facebook.android.Facebook.DialogListener() {
@Override
public void onFacebookError(FacebookError e)
{
Log.d("Jyoya", "onFacebookError");
String cMessage = e.getMessage();
if(cMessage.length() < 1)
showAlert(e.getMessage());
else
showAlert(mContext.getString(R.string.facebookMessageAuthorizationErrorDefault));
}
@Override
public void onError(DialogError e)
{
Log.d("Jyoya", "onError");
String cMessage = e.getMessage();
if(cMessage.length() < 1)
showAlert(e.getMessage());
else
showAlert(mContext.getString(R.string.facebookMessageAuthorizationErrorDefault));
}
@Override
public void onComplete(Bundle values)
{ // set activity result and finish this activity.
FacebookDialogActivity.this.setResult(Activity.RESULT_OK);
FacebookDialogActivity.this.finish();
}
@Override
public void onCancel()
{
mResultCode = Activity.RESULT_CANCELED;
FacebookDialogActivity.this.setResult(Activity.RESULT_CANCELED);
FacebookDialogActivity.this.finish();
}
private void showAlert(String message)
{
mResultCode = Activity.RESULT_CANCELED;
DialogUtil.showDefaultAlert(FacebookDialogActivity.this, message, R.string.dialogButtonCaptionOk,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int arg1) {
dialog.dismiss();
FacebookDialogActivity.this.setResult(Activity.RESULT_CANCELED);
FacebookDialogActivity.this.finish();
}
}
);
}
});
}
/**
* for Single Sign-On
*/
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Log.w("Jyoya", "onActivity Result");
if(requestCode == INTENT_CODE_FB_DIALOG && resultCode == RESULT_OK)
{
mFb.authorizeCallback(requestCode, resultCode, data);
// show a waiting dialog and wait for receiving actual result code.
showDialog(DIALOG_ID_WAITING_FOR_ERROR);
new Thread(
new Runnable()
{
public void run()
{
try {
Thread.sleep(1 * 1000);
} catch (InterruptedException e) {}
Handler cHandler = new Handler(Looper.getMainLooper());
cHandler.post(
new Runnable()
{
public void run()
{
removeDialog(DIALOG_ID_WAITING_FOR_ERROR);
if(mResultCode != Activity.RESULT_CANCELED){
FacebookDialogActivity.this.setResult(RESULT_OK);
FacebookDialogActivity.this.finish();
}
}
}
);
}
}
).start();
}
}
protected Dialog onCreateDialog(int id)
{
Dialog cDialog = new Dialog(FacebookDialogActivity.this);
switch(id)
{
case DIALOG_ID_WAITING_FOR_ERROR:
{
ProgressDialog cProgDialog = new ProgressDialog(FacebookDialogActivity.this);
cProgDialog.setCancelable(false);
cProgDialog.setMessage(mContext.getString(R.string.facebookMessageWaitingForErrorNotification));
cProgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
cProgDialog.setOwnerActivity(FacebookDialogActivity.this);
cDialog = cProgDialog;
break;
}
}
return cDialog;
}
}
NOTE: This code leaves a problem which a blank activity will be shown if users press their back button.I've tried fix the problem but I stopped not to poison the flow of Facebook Android SDK.
No comments:
Post a Comment