我正在尝试制作一个虚拟应用程序来使用 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) {}
});
}
}