Android - facebook UnsupportedOperationException при попытке отправить сообщение

Вот мой код

package mypackage.fragments;

public class TeachersDetailedFragment extends Fragment implements MyInterface,
        OnClickListener {

private Session.StatusCallback callback;
private UiLifecycleHelper uiHelper;

private Button shareButton;
private LoginButton lb;

private boolean pendingPublishReauthorization = false;
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";

public TeachersDetailedFragment() {
    super();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    Log.i("Tag:", getTag());

    ...

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

    uiHelper = new UiLifecycleHelper(getActivity(), callback);
    uiHelper.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    setRetainInstance(true);

    ...

    lb = (LoginButton) parentView.findViewById(R.id.authButton);
    lb.setFragment(this);

    shareButton = (Button) parentView.findViewById(R.id.shareButton);
    shareButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            publishStory(null, pendingPublishReauthorization);
        }
    });

    ...

    if (savedInstanceState != null) {
        pendingPublishReauthorization = savedInstanceState.getBoolean(
                PENDING_PUBLISH_KEY, false);
    }

    return parentView;
}


private void onSessionStateChange(Session session, SessionState state,
        Exception exception) {

    if (state.isOpened()) {
        shareButton.setVisibility(View.VISIBLE);
        // lb.setVisibility(View.GONE);
        if (pendingPublishReauthorization
                && state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
            pendingPublishReauthorization = false;
            publishStory(null, pendingPublishReauthorization);
        }

        Log.i("facebook", "Logged in...");
        // TODO hide logout button
    } else if (state.isClosed()) {
        shareButton.setVisibility(View.GONE);
        lb.setVisibility(View.VISIBLE);
        Log.i("facebook", "Logged out...");
    }
}


@Override
public void onResume() {
    super.onResume();
    // For scenarios where the main activity is launched and user
    // session is not null, the session state change notification
    // may not be triggered. Trigger it if it's open/closed.
    Session session = Session.getActiveSession();
    if (session != null && (session.isOpened() || session.isClosed())) {
        onSessionStateChange(session, session.getState(), null);
    }
    uiHelper.onResume();

}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    uiHelper.onActivityResult(requestCode, resultCode, data);
    Log.e("result meghívva", "meghívva ez a fos");
    // Session.getActiveSession().onActivityResult(getActivity(),
    // requestCode,
    // resultCode, data);
}

@Override
public void onPause() {
    super.onPause();
    uiHelper.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    uiHelper.onDestroy();
    MainActivity.fragmentList.remove(getTag().toString());
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(PENDING_PUBLISH_KEY, pendingPublishReauthorization);
    uiHelper.onSaveInstanceState(outState);
}

private void publishStory(List<String> PERMISSIONS,
        boolean pendingPublishReauthorization) {
    final Session session = Session.getActiveSession();

    if (session != null) {

        // Check for publish permissions
        List<String> permissions = session.getPermissions();
        try {
            if (!isSubsetOf(Arrays.asList("publish_actions"), permissions)) {
                pendingPublishReauthorization = true;
                Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(
                        getActivity(), Arrays.asList("publish_actions"));
                session.requestNewPublishPermissions(newPermissionsRequest); //ERROR HERE - line //607
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(
                    getActivity().getApplicationContext(),
                    "Sajnos nem sikerült megosztani, próbáljon újra bejelentkezni",
                    Toast.LENGTH_LONG).show();
            // session.close();
        }

        Bundle postParams = new Bundle();
        String[] images = feedItem.getImages();
        postParams.putString("name", feedItem.getFirstname() + " "
                + feedItem.getLastname() + " " + feedItem.getName());
        postParams.putString("caption", "test");
        postParams.putString("description", "test");
        postParams.putString("link", feedItem.getUrl());
        postParams.putString("picture", (Globals.BASE_URL + images[0]));

        Request.Callback callback = new Request.Callback() {
            @Override
            public void onCompleted(com.facebook.Response response) {
                try {
                    JSONObject graphResponse = response.getGraphObject()
                            .getInnerJSONObject(); //ERROR HERE - LINE 633
                    String postId = null;
                    postId = graphResponse.getString("id");
                } catch (JSONException e) {
                    Log.i("exception", "JSON error " + e.getMessage());
                }
                FacebookRequestError error = response.getError();
                if (error != null) {
                    Log.e("face megosztás hiba", error.getErrorMessage());
                    Toast.makeText(getActivity().getApplicationContext(),
                            "Sajnos nem sikerült megosztani",
                            Toast.LENGTH_SHORT).show();
                    session.close();
                } else {
                    Log.i("facebook", "sikeres post");
                    Toast.makeText(getActivity().getApplicationContext(),
                            "Sikeresen megosztva!", Toast.LENGTH_LONG)
                            .show();
                    // session.close();
                }
            }

        };

        Request request = new Request(session, "me/feed", postParams,
                HttpMethod.POST, callback);

        RequestAsyncTask task = new RequestAsyncTask(request);
        task.execute();

    }

}

private boolean isSubsetOf(Collection<String> subset,
        Collection<String> superset) {
    for (String string : subset) {
        if (!superset.contains(string)) {
            return false;
        }
    }
    return true;
}

}

Логин успешен, и после этого я пытаюсь опубликовать на Facebook, но мое приложение перестает работать, говоря в logcat следующее:

01-06 19:59:06.966: W/System.err(13701): java.lang.UnsupportedOperationException: Session: an 

attempt was made to request new permissions for a session that has a pending request.
01-06 19:59:06.967: W/System.err(13701):    at com.facebook.Session.requestNewPermissions(Session.java:1248)
01-06 19:59:06.967: W/System.err(13701):    at com.facebook.Session.requestNewPublishPermissions(Session.java:595)
01-06 19:59:06.967: W/System.err(13701):    at hu.karathb.netcar.fragments.TeachersDetailedFragment.publishStory(TeachersDetailedFragment.java:607)
01-06 19:59:06.967: W/System.err(13701):    at hu.karathb.netcar.fragments.TeachersDetailedFragment.access$2(TeachersDetailedFragment.java:594)
01-06 19:59:06.967: W/System.err(13701):    at hu.karathb.netcar.fragments.TeachersDetailedFragment$2.onClick(TeachersDetailedFragment.java:120)
01-06 19:59:06.967: W/System.err(13701):    at android.view.View.performClick(View.java:4756)
01-06 19:59:06.967: W/System.err(13701):    at android.view.View$PerformClick.run(View.java:19749)
01-06 19:59:06.967: W/System.err(13701):    at android.os.Handler.handleCallback(Handler.java:739)
01-06 19:59:06.967: W/System.err(13701):    at android.os.Handler.dispatchMessage(Handler.java:95)
01-06 19:59:06.967: W/System.err(13701):    at android.os.Looper.loop(Looper.java:135)
01-06 19:59:06.967: W/System.err(13701):    at android.app.ActivityThread.main(ActivityThread.java:5221)
01-06 19:59:06.967: W/System.err(13701):    at java.lang.reflect.Method.invoke(Native Method)
01-06 19:59:06.967: W/System.err(13701):    at java.lang.reflect.Method.invoke(Method.java:372)
01-06 19:59:06.968: W/System.err(13701):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-06 19:59:06.968: W/System.err(13701):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
01-06 19:59:07.212: D/AndroidRuntime(13701): Shutting down VM
01-06 19:59:07.214: E/AndroidRuntime(13701): FATAL EXCEPTION: main
01-06 19:59:07.214: E/AndroidRuntime(13701): Process: hu.karathb.netcar, PID: 13701
01-06 19:59:07.214: E/AndroidRuntime(13701): java.lang.NullPointerException: Attempt to invoke interface method 'org.json.JSONObject com.facebook.model.GraphObject.getInnerJSONObject()' on a null object reference
01-06 19:59:07.214: E/AndroidRuntime(13701):    at hu.karathb.netcar.fragments.TeachersDetailedFragment$8.onCompleted(TeachersDetailedFragment.java:633)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at com.facebook.Request$4.run(Request.java:1666)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at android.os.Handler.handleCallback(Handler.java:739)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at android.os.Handler.dispatchMessage(Handler.java:95)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at android.os.Looper.loop(Looper.java:135)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at android.app.ActivityThread.main(ActivityThread.java:5221)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at java.lang.reflect.Method.invoke(Native Method)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at java.lang.reflect.Method.invoke(Method.java:372)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-06 19:59:07.214: E/AndroidRuntime(13701):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

В чем может быть проблема? Спасибо за вашу помощь!

1 ответ

Здесь есть два вопроса.

Во-первых, ваше приложение запрашивает разрешения на публикацию, пока еще не завершена операция (вы опубликовали весь свой фрагмент? Кажется, что есть класс / метод TeachersDetailedFragment.access, которого здесь нет). Я думаю, это потому, что вы сначала открываете сеанс, но затем сразу же запрашиваете разрешения на публикацию до того, как закончится первое открытие. Помните, что сессия открывается (и новые запросы разрешений) асинхронные, поэтому вы должны дождаться методов onSessionStateChange, прежде чем запрашивать новые разрешения.

Во-вторых, это ваш NPE, который на самом деле разрушает ваше приложение. Это просто потому, что у вас нет результата (так как вы еще не получили разрешения), поэтому graphResponse.getGraphObject() имеет значение null, и если вы попытаетесь вызвать для него getInnerJSONObject, он выдаст NPE. Это никак не связано с SDK, но вы всегда должны выполнять нулевую проверку (или сначала проверять наличие ошибок в graphResponse).

Другие вопросы по тегам