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 に答える