0

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

1 回答 1

0

这是任何在使用 Facebook SDK 时发现自己遇到相同错误的初学者 Android 开发人员的答案。

事实证明,最近的 Android 版本要求您在与主线程分开的线程上进行所有网络调用(通过 AysncTask 或您自己的 Java 线程)。如果您确实尝试在主线程上进行网络调用,而不是挂起 UI,它只会像我所经历的那样抛出错误。

于 2012-09-30T20:14:20.370 回答