3

我正在尝试使用 android 中的 facebook SDK 做一些相当简单的事情:

  • 首先让用户登录
  • 然后向用户询问其新闻源的读取权限

我有以下代码来执行此操作:

    FacebookAlertActivity(Activity activity, Context context) {

            this.activity = activity;
            this.context = context;

                // start Facebook Login
                Session.openActiveSession(activity, true, new Session.StatusCallback() {

                // callback when session changes state
                @Override
                public void call(Session session, SessionState state, Exception exception) {
                        if (session.isOpened()) {
                                // make request to the /me API
                                Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {

                                  // callback after Graph API response with user object
                                  @Override
                                  public void onCompleted(GraphUser user, Response response) {
                                          if (user != null) {
                                                  //TextView welcome = (TextView) findViewById(R.id.welcome);
                                                  //welcome.setText("Hello " + user.getName() + "!");
                                                }
                                  }
                                });
                        }
                    }
                  });

                // pull from news feed
    Bundle params = new Bundle();
    params.putString("q", FQL_QUERY);
    Session session = Session.getActiveSession();

    // get permissions to read user's facebook feed
    requestReadPermissions(session);

requestReadPermissions looks like this:

        private void requestReadPermissions(Session session) {
            if (session != null) {
                Session.NewPermissionsRequest newPermissionsRequest = 
                    new Session.NewPermissionsRequest(activity, PERMISSIONS).
                        setRequestCode(REAUTH_ACTIVITY_CODE);
                session.requestNewPublishPermissions(newPermissionsRequest);
            }
        }

当我尝试 requestReadPermissions() 时,我收到以下错误消息:

    java.lang.RuntimeException: Unable to start activity
    ComponentInfo{com.example.alarmclock/com.example.alarmclock.AlarmHandler}:
    java.lang.UnsupportedOperationException: Session: an attempt was made 
    to request new permissions for a session that has a pending request.

有关如何解决此错误的任何想法?

完整代码:FacebookTestActivity.java

package com.example.alarmclock;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;

import com.facebook.*;
import com.facebook.android.Facebook;
import com.facebook.model.*;
import android.widget.TextView;
import android.content.Intent;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantLock;

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

public class FacebookTestActivity extends Activity {

    public ArrayList<fbPost> newsFeed = new ArrayList<fbPost>();

        // Activity code to flag an incoming activity result is due 
        // to a new permissions request
        private static final int REAUTH_ACTIVITY_CODE = 100;

        // Indicates an on-going reauthorization request
        private boolean pendingAnnounce;

        // Key used in storing the pendingAnnounce flag
        private static final String PENDING_ANNOUNCE_KEY = "pendingAnnounce";

        /// List of additional write permissions being requested
        private static final List<String> PERMISSIONS = Arrays.asList("read_stream");

    private static final String FQL_QUERY = "SELECT message, comments, " +
    "source_id, actor_id, attachment FROM stream WHERE filter_key IN (SELECT filter_key FROM " +
    "stream_filter WHERE uid=me() AND type='newsfeed')";

    private static final String FQL_ID_TO_NAME_QUERY = "SELECT name FROM user WHERE uid = ";

    private final ReentrantLock lock = new ReentrantLock();

    public String nameFromID;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_facebook_alert);

                // start Facebook Login
                  Session.openActiveSession(this, true, new Session.StatusCallback() {

                    // callback when session changes state
                    @Override
                    public void call(Session session, SessionState state, Exception exception) {
                        if (session.isOpened()) {
                                // make request to the /me API
                                Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {

                                  // callback after Graph API response with user object
                                  @Override
                                  public void onCompleted(GraphUser user, Response response) {
                                          if (user != null) {
                                                  TextView welcome = (TextView) findViewById(R.id.welcome);
                                                  welcome.setText("Hello " + user.getName() + "!");
                                                }
                                  }
                                });
                        }
                    }
                  });

                // pull from news feed
            Bundle params = new Bundle();
        params.putString("q", FQL_QUERY);
        Session session = Session.getActiveSession();

        // get permissions to read user's facebook feed
        requestReadPermissions(session);

        // apparently a bad practice...
        sketchyCode();

        Request request = new Request(session,
            "/fql",                         
            params,                         
            HttpMethod.GET,                 
            new Request.Callback(){
                public void onCompleted(Response response) {
                        //response.getClass();
                        GraphObject feed = response.getGraphObject();

                        if (feed != null){
                                JSONObject jsonObject = feed.getInnerJSONObject();
                                JSONArray arr;

                                                try {
                                                        arr = jsonObject.getJSONArray("data");

                                                String s = Integer.toString(newsFeed.size());
                                                Log.d("fbPost::onCompleted", s);

                                                        for (int i = 0; i < arr.length(); i++) {
                                                    JSONObject object = (JSONObject) arr.get(i);
                                                    test(translateJSONToPost(object));
                                                    newsFeed.add(translateJSONToPost(object));
                                                    Log.d("TAG", "message = "+object.get("message"));
                                                 }
                                                } catch (JSONException e) {
                                                        // TODO Auto-generated catch block
                                                        e.printStackTrace();
                                                }

                    Log.i("TAG", "Result: " + response.toString());
                        }
                    }
                }); 

        Request.executeBatchAndWait(request);

        String s = Integer.toString(newsFeed.size());

        Log.d("fbPost::after", s);
        s = Integer.toString(newsFeed.size());

        Log.d("fbPost", s);
        for (int i=0; i<newsFeed.size(); i++){
                newsFeed.get(i).print();
        }
        }

        public void onClick(View v){
        String s = Integer.toString(newsFeed.size());
                Log.d("onClick::fbPost", s);
        for (int i=0; i<newsFeed.size(); i++){
                newsFeed.get(i).print();
        }
        }

        public void test(fbPost post){
        String s = Integer.toString(newsFeed.size());

                newsFeed.add(post);

        s = Integer.toString(newsFeed.size());
        Log.d("test(): fbPost", s);
        }

        private fbPost translateJSONToPost(JSONObject object) throws JSONException {
                fbPost post;
                JSONObject attach;

                String actor_id;
                String actor_name;
                String source_id;
                String source_name;

                actor_id = object.getString("actor_id");
                source_id = object.getString("source_id");

                actor_name = getNameFromID(actor_id);
                source_name = getNameFromID(source_id);

                // before processing the update as a regular status update,
                // try to read it in as a Youtube link or a regular link
                try {
                        attach = object.getJSONObject("attachment");

                        JSONArray media = attach.getJSONArray("media");
                        Log.d("2TAG", media.toString());

                        if (media.toString().equals("[]")){
                                //Log.d("2TAG", "i failed you (media)");
                                post = new linkPost(attach.getString("description"), actor_name, source_name);
                                return post;
                        }
                        post = new videoLinkPost(attach.getString("description"), attach.getString("href"), actor_name, source_name);
                        return post;
                        //linkPost thing = (linkPost) post;
                        //Log.d("2TAG", "message: " + post.message + " URL: " + thing.linkURL );
                } catch (JSONException e) {
                        // Means we were NOT able to retrieve an attachment from the post (indicating it
                        // is a regular status update)!
                        //Log.d("2TAG", "i failed you");
                        e.printStackTrace();
                }

                // now that we know its not a link, then we can treat it as a regular post
                try {
                        post = new statusPost(object.getString("message"), actor_name, source_name);
                        return post;
                } catch (JSONException e) {
                        Log.d("2TAG", "this type of post is not supported by our processing engine yet.");
                        return null;
                }               
        }

        private String getNameFromID(String id){
                sketchyCode();

            Bundle params = new Bundle();
        params.putString("q", FQL_ID_TO_NAME_QUERY + id);
        Session session = Session.getActiveSession();

                Request request = new Request(session,
                    "/fql",                         
                    params,                         
                    HttpMethod.GET,                 
                    new Request.Callback(){         
                        public void onCompleted(Response response) {
                                GraphObject data = response.getGraphObject();

                                if (data != null){
                                        JSONObject jsonObject = data.getInnerJSONObject();
                                        JSONArray arr;

                                                        try {
                                                                arr = jsonObject.getJSONArray("data");

                                                                JSONObject user = (JSONObject) arr.get(0);
                                                                nameFromID = user.getString("name");

                                                        } catch (JSONException e) {
                                                                // TODO Auto-generated catch block
                                                                e.printStackTrace();
                                                        }
                                }

                            Log.i("TAG", "Result: " + response.toString());
                        }                
                });

                Request.executeBatchAndWait(request);
                return nameFromID;

        }

        private void requestReadPermissions(Session session) {
            if (session != null) {
                Session.NewPermissionsRequest newPermissionsRequest = 
                    new Session.NewPermissionsRequest(this, PERMISSIONS).
                        setRequestCode(REAUTH_ACTIVITY_CODE);
                session.requestNewPublishPermissions(newPermissionsRequest);
            }
        }

        // to allow for non-asynchronous calls to Facebook batch handling methods
        private void sketchyCode(){
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy); 
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.activity_facebook_alert, menu);
                return true;
        }

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

}

完整代码:activity_facebook_alert.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FacebookAlertActivity" >

    <TextView
        android:id="@+id/welcome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="facebook" 
        android:onClick="onClick"
        android:clickable="true"/>

</RelativeLayout>
4

2 回答 2

1

Session.openActiveSession()返回一个会话,请改用该会话。您Session.getActiveSession()用于请求读取权限。请记住,它call()是异步的,它也可以被多次调用,直到会话的状态被打开。您的代码将Session.openActiveSession()在 Session 达到打开状态之前达到。

此外,您应该检查state.isOpened()而不是检查,session.isOpened()因为您正在等待可以发出请求的打开状态。

于 2013-09-05T01:22:05.017 回答
0

每当您尝试为已打开且先前具有相同权限集的会话设置权限时,您都会遇到此异常。

所以只使用一次 requestReadPermissions() ,即当使用 Session.openActiveSession(this, true, new Session.StatusCallback() { ..}); 创建会话时

例如

Session session = Session.getActiveSession();
if (session != null)
{
        proceed();
}

else
{
    Session.openActiveSession(MainActivity.this, true,
                        new Session.StatusCallback()
                        {
                            @Override
                            public void call(Session session,
                                    SessionState state, Exception exception)
                            {
                                if (session.isOpened())
                                {
                                    requestReadPermissions(session);
                                    proceed();
                                }
                            }
                        });

}
于 2014-07-03T14:16:08.243 回答