Facebook の Android SDK をいじるダミーアプリを作ろうとしています。現在 SSO を使用しており、次のコードで認証トークンを保存できます。基本的には、サインオンするだけで、userId を取得するための呼び出しを行い、テスト ボタンをクリックして画面に表示するときに別の呼び出しを行うことになっています。
認証トークンは正常に出力されますが、グラフを呼び出そうとすると Facebook エラーがスローされ続けます。奇妙なことに、ログからリクエストをコピーしてブラウザに投稿すると、有効な json レスポンスが返されます。
Facebook から直接呼び出すのは理想的ではないことはわかっていますが (洗練されたアプリには非同期要求の方が適している可能性があります)、現時点では、基本的な API を機能させようとしています。
助言がありますか?
//Standard Android imports
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.android.Util;
//Facebook Imports
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
//Something to test and increment to know things are changing
private static int changeCounter;
//Create a new Facebook object with the Facebook App ID (found on the facebook app online)
public String APP_ID;
Facebook facebook;
private SharedPreferences mPrefs;
//For Facebook Async tasks
private AsyncFacebookRunner mAsyncRunner;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
APP_ID = getString(R.string.APP_ID);
facebook = new Facebook(APP_ID);
mAsyncRunner = new AsyncFacebookRunner(facebook);
changeCounter = 0;
//Add a button
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Perform action on click
Log.v(TAG, "logout button clicked!");
logoutOfFacebook();
}
});
Button testButton = (Button) findViewById(R.id.button2);
testButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.v(TAG, "testButton clicked");
testViewPrint();
}
});
checkFBAccessToken();
}
//Checks if there is an access token in the private mPrefs file and renews
//the token if it is non existent or out of date
private void checkFBAccessToken() {
/* Get existing access_token if any */
mPrefs = getPreferences(MODE_PRIVATE);
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if (access_token != null) {
facebook.setAccessToken(access_token);
}
if (expires != 0) {
facebook.setAccessExpires(expires);
}
/* Only call authorize if the access_token has expired */
if (!facebook.isSessionValid()) {
renewFBAccessToken();
}
}
//Renews the Facebook access Token and stores in the MODE_PRIVATE SharedPreferences
private void renewFBAccessToken() {
//Facebook permissions
String[] permissions = { "user_location", "friends_location", "email" };
facebook.authorize(this, permissions, new DialogListener() {
//@Override
public void onComplete(Bundle values) {
SharedPreferences.Editor editor = mPrefs.edit();
//Get the access token
editor.putString("access_token", facebook.getAccessToken());
editor.putLong("access_expires", facebook.getAccessExpires());
editor.commit();
//Test the user information recieved
printUIDAndAuthToken();
}
//@Override
public void onFacebookError(FacebookError error) {}
public void onError(DialogError e) {
Log.e(TAG, "There was an error logging out: " + e);
}
public void onCancel() {
Log.d(TAG, "onCancel was hit");
}
});
}
//Prints the UID and AuthToken to the text view for testing purposes
private void printUIDAndAuthToken() {
TextView printOutView = (TextView)findViewById(R.id.textView2);
String authTokenStr = mPrefs.getString("access_token", "Did not get any AuthToken.");
String uIdStr = mPrefs.getString("user_id", "Did not get any UID");
printOutView.setText(changeCounter++ + uIdStr + " | \n" + authTokenStr);
}
private void getFBUserId() {
//Also try to get and store the UID
SharedPreferences.Editor editor = mPrefs.edit();
try {
Bundle params = new Bundle();
params.putString("acess_token", facebook.getAccessToken());
editor.putLong("access_expires", facebook.getAccessExpires());
Log.v(TAG, facebook.getAccessToken() + " ||| =>");
String jsonStringResponse = facebook.request("me", params);
Log.v(TAG, jsonStringResponse);
JSONObject json = new JSONObject(jsonStringResponse);
String userId;
userId = json.getString("id");
editor.putString("user_id", userId);
} catch (MalformedURLException m) {
Log.e(TAG, "MalformedURLException");
m.printStackTrace();
} catch (IOException i) {
Log.e(TAG, "IOException Caught");
i.printStackTrace();
} catch (Exception e) {
//Catch possible exception from request
Log.e(TAG, "JSON or Facebook Error getting user ID: ");
//Log.e(TAG, e.getMessage());
}
editor.commit();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
//Prints out a bunch of testing info in the view
private void testViewPrint() {
//Testing
getFBUserId();
printUIDAndAuthToken();
}
//Code called by the button to logout of Facebook
private void logoutOfFacebook() {
mAsyncRunner.logout(this, new RequestListener() {
@Override
public void onComplete(String response, Object state) {}
@Override
public void onIOException(IOException e, Object state) {}
@Override
public void onFileNotFoundException(FileNotFoundException e, Object state) {}
@Override
public void onMalformedURLException(MalformedURLException e, Object state) {}
public void onFacebookError(FacebookError e, Object state) {}
});
}
}