2013-03-07 219 views
3

我想利用Facebook SDK 3.0的Android做一些簡單的圖形請求。正如我不會用Fragment S,我不能使用張貼在Facebook的開發者文檔中的樣本。的Facebook SDK 3.0的Android不片段不起作用

我有一些簡單的Activity旗下成立了,但他們沒有工作。我問有賞金herehere問題。但這並沒有真正的幫助。

在此期間,我一直在閱讀很多關於Facebook SDK的帖子,並嘗試了幾十個小時,但沒有成功。最後,我在this blog上找到了一個額外的代碼示例。所以,我已經建立了完整的Activity是打印所有朋友的家鄉到logcat的。

但是,這並不工作,無論是。相反,它只會請求基本權限(公共信息+朋友列表),然後退出。我究竟做錯了什麼? Facebook應用程序的關鍵哈希,包名和類名被設置,LogCat上沒有什麼有趣的內容。

package com.my.package; 

import java.util.Arrays; 
import java.util.Date; 
import java.util.List; 
import org.json.JSONArray; 
import org.json.JSONObject; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.preference.PreferenceManager; 
import android.widget.Toast; 
import com.facebook.*; 

public class FBRequest extends Activity { 

    private static final String PERMISSION_FRIENDS_HOMETOWN = "friends_hometown"; 
    private static final String PREFERENCE_ACCESS_TOKEN = "facebookAccessToken"; 
    private static final String PREFERENCE_EXPIRATION_DATE = "facebookAccessTokenExpires"; 
    private ProgressDialog mProgress; 
    private SharedPreferences mPrefs; 

    private void showToast(final String text) { 
     runOnUiThread(new Runnable() { 
      public void run() { 
       Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show(); 
      } 
     }); 
    } 

    protected void onCreate(final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mPrefs = PreferenceManager.getDefaultSharedPreferences(this); 
     try { 
      startFacebookRequest(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     Session session = Session.getActiveSession(); 
     if (session != null) { 
      session.onActivityResult(this, requestCode, resultCode, data); 
     } 
    } 

    public interface FacebookConnectHandler { 
     public void onSuccess(); 
     public void onFailure(); 
    } 

    public void startFacebookRequest() { 
     connectToFacebook(new FacebookConnectHandler() { 
      @Override 
      public void onSuccess() { 
       // safety check 
       if (isFinishing()) { return; } 

       showProgressDialog("Connecting to Facebook ..."); 

       // check for publish permissions 

       final List<String> permissions_required = Arrays.asList(PERMISSION_FRIENDS_HOMETOWN); 

       if (Session.getActiveSession().getPermissions() == null || !Session.getActiveSession().getPermissions().containsAll(permissions_required)) { 
        // need to make a Session.openActiveSessionFromCache(...) call 
        // because of a bug in the Facebook sdk 
        // where a second call to get permissions 
        // won't result in a session callback when the token is updated 

        if (Session.openActiveSessionFromCache(FBRequest.this) == null) { 
         showToast("Could not connect to Facebook! (3)"); 
         return; 
        } 

        Session.getActiveSession().addCallback(new Session.StatusCallback() { 
         @Override 
         public void call(Session session, SessionState state, Exception exception) { 
          if (exception != null || state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { 
           // didn't get required permissions 

           session.removeCallback(this); 

           // safety check 
           if (!isFinishing()) { 
            showToast("Could not connect to Facebook! (4)"); 
           } 
          } 
          else if (state.equals(SessionState.OPENED_TOKEN_UPDATED) && session.getPermissions().containsAll(permissions_required)) { 
           // got required permissions 

           session.removeCallback(this); 

           // safety check 
           if (!isFinishing()) { 
            startFacebookRequest(); 
           } 
          } 
         } 
        }); 

        Session.getActiveSession().requestNewReadPermissions(new Session.NewPermissionsRequest(FBRequest.this, permissions_required)); 
        return; 
       } 
       startGraphRequest(Session.getActiveSession()); 
      } 


      @Override 
      public void onFailure() { 
       cancelProgressDialog(); 
       showToast("Could not connect to Facebook! (1)"); 
      } 
     }); 
    } 

    private void startGraphRequest(Session session) { 
     Request.executeGraphPathRequestAsync(session, "me/friends/?access_token="+session.getAccessToken()+"&fields=id,name,hometown&limit=500", new Request.Callback() { 
      @Override 
      public void onCompleted(Response response) { 
       if (response != null) { 
        try { 
         JSONArray jarr = response.getGraphObject().getInnerJSONObject().getJSONArray("data"); 
         JSONObject entry; 
         StringBuilder backupStr = new StringBuilder(); 
         int nExistingEntries = existingEntries.length; 
         for (int i = 0; i < jarr.length(); i++) { 
          entry = jarr.getJSONObject(i); 
          if (!entry.isNull("id") && !entry.isNull("name") && !entry.isNull("hometown")) { 
           System.out.println(entry.getString("hometown")); 
          } 
         } 
        } 
        catch (Exception e) { 
         e.printStackTrace(); 
         showToast("Unexpected error!"); 
        } 
       } 
      } 
     }); 
    } 

    private void connectToFacebook(final FacebookConnectHandler handler) { 

     // check whether the user already has an active session 
     // and try opening it if we do 

     // (note: making a Session.openActiveSessionFromCache(...) call 
     // instead of simply checking whether the active session is opened 
     // because of a bug in the Facebook sdk 
     // where successive calls to update a token 
     // (requesting additional permissions etc) 
     // don't result in a session callback) 

     if (Session.getActiveSession() != null && Session.openActiveSessionFromCache(this) != null) { 
      handler.onSuccess(); 
      return; 
     } 

     // initialise the session status callback 

     Session.StatusCallback callback = new Session.StatusCallback() { 
      @Override 
      public void call(Session session, SessionState state, Exception exception) { 

       if (isFinishing()) { return; } 

       // check session state 

       if (state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { 

        clearFacebookSharedPreferences(); 

        // specific action for when the session is closed 
        // because an open-session request failed 
        if (state.equals(SessionState.CLOSED_LOGIN_FAILED)) { 
         cancelProgressDialog(); 
         handler.onFailure(); 
        } 
       } 
       else if (state.equals(SessionState.OPENED)) { 
        cancelProgressDialog(); 

        saveFacebookSharedPreferences(session.getAccessToken(), session.getExpirationDate().getTime()); 

        showToast("Succeeded connecting to Facebook"); 

        handler.onSuccess(); 
       } 
      } 
     }; 

     // make the call to open the session 

     showProgressDialog("Connecting to Facebook..."); 

     if (Session.getActiveSession() == null && mPrefs.contains(PREFERENCE_ACCESS_TOKEN) && mPrefs.contains(PREFERENCE_EXPIRATION_DATE)) { 
      // open a session from the access token info 
      // saved in the app's shared preferences 

      String accessTokenString = mPrefs.getString(PREFERENCE_ACCESS_TOKEN, ""); 

      Date accessTokenExpires = new Date(mPrefs.getLong(PREFERENCE_EXPIRATION_DATE, 0)); 

      AccessToken accessToken = AccessToken.createFromExistingAccessToken(accessTokenString, accessTokenExpires, null, null, null); 

      Session.openActiveSessionWithAccessToken(this, accessToken, callback); 
     } 
     else { 
      // open a new session, logging in if necessary 
      Session.openActiveSession(this, true, callback); 
     } 
    } 

    private void saveFacebookSharedPreferences(final String token, final long expiration) { 
     if (mPrefs != null) { 
      SharedPreferences.Editor editor = mPrefs.edit(); 
      editor.putString(PREFERENCE_ACCESS_TOKEN, token); 
      editor.putLong(PREFERENCE_EXPIRATION_DATE, expiration); 
      editor.commit(); 
     } 
    } 

    private void clearFacebookSharedPreferences() { 
     if (mPrefs != null) { 
      SharedPreferences.Editor editor = mPrefs.edit(); 
      editor.remove(PREFERENCE_ACCESS_TOKEN); 
      editor.remove(PREFERENCE_EXPIRATION_DATE); 
      editor.commit(); 
     } 
    } 

    private void showProgressDialog(final String text) { 
     mProgress = ProgressDialog.show(getApplicationContext(), "Facebook", text, true, false); 
    } 

    private void cancelProgressDialog() { 
     if (mProgress != null) { 
      if (mProgress.isShowing()) { 
       mProgress.dismiss(); 
      } 
      mProgress = null; 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     cancelProgressDialog(); 
    } 

} 

在此先感謝!

編輯:代碼工作,但我沒有叫setContentView()Activityfinish()被稱爲在一個錯誤的情況。這就是爲什麼人們無法看到(擴展)權限的第二個請求。

+0

您是否收到任何錯誤或您沒有得到您想要的?你究竟想要什麼? – Shoshi 2013-03-09 15:31:19

+0

我沒有收到任何錯誤,但我沒有收到我真正想要的內容。我想要的是在問題中描述:「將所有朋友的家鄉打印到LogCat」 – caw 2013-03-09 16:12:21

回答

9

上面的代碼只是我做即同時顯示對話框其給予例外窗口壞令牌這個我已經改變背景進步小的變化是工作的罰款。而且我還評論了一條不使用'existingEntries'的行。

我可以登錄和應用程序詢問訪問朋友訪問家鄉的權限。我可以看到朋友ID和他們的家鄉。

更新工作版本:

package com.example.options; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Date; 
import java.util.List; 

import org.json.JSONArray; 
import org.json.JSONObject; 

import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.preference.PreferenceManager; 
import android.widget.Toast; 

import com.facebook.AccessToken; 
import com.facebook.Request; 
import com.facebook.Response; 
import com.facebook.Session; 
import com.facebook.Session.Builder; 
import com.facebook.Session.NewPermissionsRequest; 
import com.facebook.Session.OpenRequest; 
import com.facebook.SessionLoginBehavior; 
import com.facebook.SessionState; 

public class FBRequest extends Activity { 

    private static final String PERMISSION_FRIENDS_HOMETOWN = "friends_hometown"; 
    private static final String PREFERENCE_ACCESS_TOKEN = "facebookAccessToken"; 
    private static final String PREFERENCE_EXPIRATION_DATE = "facebookAccessTokenExpires"; 
    private ProgressDialog mProgress; 
    private SharedPreferences mPrefs; 

    private void showToast(final String text) { 
     runOnUiThread(new Runnable() { 
      public void run() { 
       Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show(); 
      } 
     }); 
    } 

    protected void onCreate(final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mPrefs = PreferenceManager.getDefaultSharedPreferences(this); 
     try { 
      startFacebookRequest(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 

     if(resultCode == RESULT_OK && requestCode == Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE) 
     { 
      Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); 
      Session session = Session.getActiveSession(); 

      if (session != null && !session.isClosed()) 
      { 
       startFacebookRequest(); 
      } 
     } 
    } 

    public interface FacebookConnectHandler { 
     public void onSuccess(); 
     public void onFailure(); 
    } 

    public void startFacebookRequest() { 
     connectToFacebook(new FacebookConnectHandler() { 
      @Override 
      public void onSuccess() { 
       // safety check 
       if (isFinishing()) { return; } 

       showProgressDialog("Connecting to Facebook ..."); 

       // check for publish permissions 

       final List<String> permissions_required = Arrays.asList(PERMISSION_FRIENDS_HOMETOWN); 

       if (Session.getActiveSession().getPermissions() == null || !Session.getActiveSession().getPermissions().containsAll(permissions_required)) { 
        // need to make a Session.openActiveSessionFromCache(...) call 
        // because of a bug in the Facebook sdk 
        // where a second call to get permissions 
        // won't result in a session callback when the token is updated 

        if (Session.openActiveSessionFromCache(FBRequest.this) == null) { 
         showToast("Could not connect to Facebook! (3)"); 
         return; 
        } 

        Session.getActiveSession().addCallback(new Session.StatusCallback() { 
         @Override 
         public void call(Session session, SessionState state, Exception exception) { 
          if (exception != null || state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { 
           // didn't get required permissions 

           session.removeCallback(this); 

           // safety check 
           if (!isFinishing()) { 
            showToast("Could not connect to Facebook! (4)"); 
           } 
          } 
          else if (state.equals(SessionState.OPENED_TOKEN_UPDATED) && session.getPermissions().containsAll(permissions_required)) { 
           // got required permissions 

           session.removeCallback(this); 

           // safety check 
           if (!isFinishing()) { 
            startFacebookRequest(); 
           } 
          } 
         } 
        }); 

        NewPermissionsRequest req = new Session.NewPermissionsRequest(FBRequest.this, permissions_required); 
        req.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO); 
        Session.getActiveSession().requestNewReadPermissions(req); 
        return; 
       } 
       startGraphRequest(Session.getActiveSession()); 
      } 


      @Override 
      public void onFailure() { 
       cancelProgressDialog(); 
       showToast("Could not connect to Facebook! (1)"); 
      } 
     }); 
    } 

    private void startGraphRequest(Session session) { 
     Request.executeGraphPathRequestAsync(session, "me/friends/?access_token="+session.getAccessToken()+"&fields=id,name,hometown&limit=500", new Request.Callback() 
     { 
      @Override 
      public void onCompleted(Response response) { 
       if (response != null) { 
        try { 
         JSONArray jarr = response.getGraphObject().getInnerJSONObject().getJSONArray("data"); 
         JSONObject entry; 
         StringBuilder backupStr = new StringBuilder(); 
//      int nExistingEntries = existingEntries.length; 
         for (int i = 0; i < jarr.length(); i++) { 
          entry = jarr.getJSONObject(i); 
          if (!entry.isNull("id") && !entry.isNull("name") && !entry.isNull("hometown")) { 
           System.out.println(entry.getString("hometown")); 
          } 
         } 
        } 
        catch (Exception e) { 
         e.printStackTrace(); 
         showToast("Unexpected error!"); 
        } 

        showToast("Friends list populated"); 
        cancelProgressDialog(); 
       } 
      } 
     }); 
    } 

    private void connectToFacebook(final FacebookConnectHandler handler) { 

     // check whether the user already has an active session 
     // and try opening it if we do 

     // (note: making a Session.openActiveSessionFromCache(...) call 
     // instead of simply checking whether the active session is opened 
     // because of a bug in the Facebook sdk 
     // where successive calls to update a token 
     // (requesting additional permissions etc) 
     // don't result in a session callback) 

     if (Session.getActiveSession() != null && Session.openActiveSessionFromCache(this) != null) { 
      handler.onSuccess(); 
      return; 
     } 

     // initialise the session status callback 

     Session.StatusCallback callback = new Session.StatusCallback() { 
      @Override 
      public void call(Session session, SessionState state, Exception exception) { 

       if (isFinishing()) { return; } 

       // check session state 

       if (state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { 

        clearFacebookSharedPreferences(); 

        // specific action for when the session is closed 
        // because an open-session request failed 
        if (state.equals(SessionState.CLOSED_LOGIN_FAILED)) { 
         cancelProgressDialog(); 
         handler.onFailure(); 
        } 
       } 
       else if (state.equals(SessionState.OPENED)) { 
        cancelProgressDialog(); 

        saveFacebookSharedPreferences(session.getAccessToken(), session.getExpirationDate().getTime()); 

        showToast("Succeeded connecting to Facebook"); 

        handler.onSuccess(); 
       } 
      } 
     }; 

     // make the call to open the session 

     showProgressDialog("Connecting to Facebook..."); 

     if (Session.getActiveSession() == null && mPrefs.contains(PREFERENCE_ACCESS_TOKEN) && mPrefs.contains(PREFERENCE_EXPIRATION_DATE)) { 
      // open a session from the access token info 
      // saved in the app's shared preferences 

      String accessTokenString = mPrefs.getString(PREFERENCE_ACCESS_TOKEN, ""); 

      Date accessTokenExpires = new Date(mPrefs.getLong(PREFERENCE_EXPIRATION_DATE, 0)); 

      AccessToken accessToken = AccessToken.createFromExistingAccessToken(accessTokenString, accessTokenExpires, null, null, null); 

      Session.openActiveSessionWithAccessToken(this, accessToken, callback); 
     } 
     else { 
      // open a new session, logging in if necessary 
      OpenRequest op = new Session.OpenRequest(this); 

      op.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO); 
      op.setCallback(null); 

      List<String> permissions = new ArrayList<String>(); 
      permissions.add(PERMISSION_FRIENDS_HOMETOWN); 
      op.setPermissions(permissions); 

      Session session = new Builder(this).build(); 
      Session.setActiveSession(session); 
      session.openForRead(op); 
     } 
    } 

    private void saveFacebookSharedPreferences(final String token, final long expiration) { 
     if (mPrefs != null) { 
      SharedPreferences.Editor editor = mPrefs.edit(); 
      editor.putString(PREFERENCE_ACCESS_TOKEN, token); 
      editor.putLong(PREFERENCE_EXPIRATION_DATE, expiration); 
      editor.commit(); 
     } 
    } 

    private void clearFacebookSharedPreferences() { 
     if (mPrefs != null) { 
      SharedPreferences.Editor editor = mPrefs.edit(); 
      editor.remove(PREFERENCE_ACCESS_TOKEN); 
      editor.remove(PREFERENCE_EXPIRATION_DATE); 
      editor.commit(); 
     } 
    } 

    private void showProgressDialog(final String text) { 
     cancelProgressDialog(); 
     mProgress = ProgressDialog.show(FBRequest.this, "Facebook", text, true, false); 
    } 

    private void cancelProgressDialog() { 
     if (mProgress != null) { 
      if (mProgress.isShowing()) { 
       mProgress.dismiss(); 
      } 
      mProgress = null; 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     cancelProgressDialog(); 
    } 

} 

的logcat:

...... 
...... 
03-11 18:57:26.781: I/System.out(6729): {"id":"10555075614xxxx","name":"Khammam"} 
03-11 18:57:26.781: I/System.out(6729): {"id":"11042167564xxxx","name":"Warangal, India"} 
03-11 18:57:26.789: I/System.out(6729): {"id":"11042167564xxxx","name":"Warangal, India"} 
03-11 18:57:26.796: I/System.out(6729): {"id":"13074615695xxxx","name":"Jaggayyapet, India"} 
03-11 18:57:26.812: I/System.out(6729): {"id":"12530386417xxxx","name":"Kodada, India"} 
03-11 18:57:26.812: I/System.out(6729): {"id":"11047265564xxxx","name":"Vishakhapatnam, Andhra Pradesh, India"} 

更新:

在第一次登錄,它要求所有的權限,並刪除SSO登錄,因爲我有未使用本地應用程序配置我的Facebook應用程序(使用密鑰存儲區散列鍵)。

+0

謝謝!第一次啓動這個「活動」後,立即要求獲得基本許可(第一次),然後在第二步中訪問「家鄉」字段?因爲對我而言,它只請求基本權限,然後關閉所有對話框。如果我再次打開它,它只是再次要求基本權限。 – caw 2013-03-11 13:57:44

+0

在接受填充的logcat後,它會在一頁中詢問基本的認可和家鄉許可。現在我已經更新了上面的代碼。檢查一下。 – Santhosh 2013-03-12 07:10:31

+0

你說得對,代碼(你以前的版本)正在工作,問題在於其他一些(較小的)細節。 – caw 2013-03-13 00:46:45

-2

使用後的Facebook SDK https://github.com/facebook/facebook-android-sdk/

以下是爲您的要求(從Facebook獲取好友列表)

try { 

    Facebook mFacebook = new Facebook(Constants.FB_APP_ID); 
    AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(mFacebook); 
    Bundle bundle = new Bundle(); 
    bundle.putString("fields", "birthday"); 
    mFacebook.request("me/friends", bundle, new FriendListRequestListener()); 

} catch(Exception e){ 
    Log.e(Constants.LOGTAG, " " + CLASSTAG + " Exception = "+e.getMessage()); 
} 

public class FriendListRequestListener extends BaseRequestListener { 

    public void onComplete(final String response) { 
     _error = null; 

     try { 
      JSONObject json = Util.parseJson(response); 
      final JSONArray friends = json.getJSONArray("data"); 

      FacebookActivity.this.runOnUiThread(new Runnable() { 
       public void run() { 
        // Do stuff here with your friends array, 
        // which is an array of JSONObjects. 
       } 
      }); 

     } catch (JSONException e) { 
      _error = "JSON Error in response"; 
     } catch (FacebookError e) { 
      _error = "Facebook Error: " + e.getMessage(); 
     } 

     if (_error != null) 
     { 
      FacebookActivity.this.runOnUiThread(new Runnable() { 
       public void run() { 
        Toast.makeText(getApplicationContext(), "Error occurred: " + 
            _error, Toast.LENGTH_LONG).show(); 
       } 
      }); 
     } 
    } 
} 

我希望它能幫助你&別人的代碼。

+0

謝謝。首先,這不是SDK的最新版本,因爲Facebook開始在SDK 3.0版本(最終版本)開始在其網站(而不是GitHub)上託管SDK。其次,這是一個簡單而簡單的例子,因爲它只輸出不需要進一步權限的好友列表。 – caw 2013-03-12 18:44:53

+0

@MarcoW。感謝您的意見。我現在將嘗試最新的Facebook SDK。 我提供了簡單明瞭的代碼,因爲它在我的一個應用程序中進行了測試,我以爲你只是想要朋友列表:) – Umang9 2013-03-13 05:19:43