2012-09-05 57 views
0

我試圖製作一個虛擬應用程序來玩Facebook的Android SDK。我目前擁有SSO,並可以使用以下代碼存儲身份驗證令牌。從本質上講,它只是登錄,然後應該打電話來獲取userId,然後再單擊測試按鈕將其打印在屏幕上時再次調用。Android上的Facebook圖形請求錯誤

身份驗證令牌打印質量很好,但當我嘗試調用圖形時,我不斷收到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) {} 
     }); 
    } 
} 

回答

0

下面是任何初學Android開發人員在使用Facebook SDK時發現自己出現相同錯誤的答案。

事實證明,最新的Android版本要求您在與主線程(通過AysncTask或您自己的Java線程)分離的線程上進行所有網絡調用。如果您確實嘗試在主線程上進行網絡調用,而不是懸掛UI,則會在我遇到時發生錯誤。