wake-up-neo.com

Android Facebook api 3.0-Fehler: LoginActivity kann nicht mit einem NULL-Aufrufpaket aufgerufen werden

Ich versuche, eine Android-App in die neue Facebook 3.0-API zu integrieren, aber ich bekomme diese Ausnahme:

Java.lang.RuntimeException: Aktivität kann nicht fortgesetzt werden {dk.imu.konnekt/com.facebook.LoginActivity}: com.facebook.FacebookException: LoginActivity kann nicht mit einem Paket mit null Aufrufen aufgerufen werden. Dies kann auftreten, wenn der launchMode des Aufrufers singleInstance ist.

Ich habe nach diesem Fehler gesucht, aber sonst scheint niemand etwas damit zu tun zu haben. Ich vermute, es liegt daran, dass ich für jede Registerkarte einen TabHost und TabsGroupActivities verwende. Aber ich habe keine Ahnung, wie ich es lösen soll.

Ich habe den entsprechenden Code hier hinzugefügt:

public class MainTabActivity extends TabActivity {    
    public void onCreate(Bundle savedInstanteState){
        super.onCreate(savedInstanteState);
        setContentView(R.layout.tab_layout);
        TabHost tabHost = getTabHost();

        View shareTab = getLayoutInflater().inflate(R.layout.share_tab, null);
        tabHost.addTab(tabHost.newTabSpec("Share").setIndicator(shareTab)
        .setContent(new Intent(MainTabActivity.this, ShareGroupActivity.class)));

        ...
    }
}

-

public class ShareGroupActivity extends TabsGroupActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startChildActivity("ShareActivity", new Intent(this, ShareActivity.class));
    }
}

-

public class ShareActivity extends BaseActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.share);

        testFacebookConnection();
    }

    public void testFacebookConnection(){
        Session session = new Session(this);
        Session.setActiveSession(session);
        SessionState state = session.getState();

        Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);

        Session.StatusCallback statusCallback = 
            new Session.StatusCallback() {
            @Override
            public void call(Session session, SessionState state, Exception exception) {
                Toast.makeText(ShareActivity.this, "Facebook session status changed", Toast.LENGTH_SHORT).show(); 
            }
        };

        if (!session.isOpened() && !session.isClosed() && session.getState() != SessionState.OPENING) {
            OpenRequest open = new OpenRequest(this).setCallback(statusCallback);
            List<String> permission = new ArrayList<String>();
            permission.add("publish_actions");
            open.setPermissions(permission);
            session.openForPublish(open);
        } else {
            Session.openActiveSession(this, true, statusCallback);
        }
    }   

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

Irgendwelche Hinweise zur Lösung?

1 Stack-Trace aktualisieren:

FATALE AUSNAHME: main Java.lang.RuntimeException: Aktivität kann nicht fortgesetzt werden {dk.imu.konnekt/com.facebook.LoginActivity}: com.facebook.FacebookException: LoginActivity kann nicht mit einem Paket ohne Aufruf von null aufgerufen werden. Dies kann auftreten, wenn der launchMode des Aufrufers singleInstance ist. um Android.app.ActivityThread.performResumeActivity (ActivityThread.Java:2812) um Android.app.ActivityThread.handleResumeActivity (ActivityThread.Java:2851) um Android.app.ActivityThread.handleLaunchActivity (ActivityThread.Java:2234) um Android.app. ActivityThread.access $ 600 (ActivityThread.Java:139) bei Android.app.ActivityThread $ H.handleMessage (ActivityThread.Java:1261) bei Android.os.Handler.dispatchMessage (Handler.Java:99) Android.os.Looper.loop (Looper.Java:154) bei Android.app.ActivityThread.main (ActivityThread.Java:4945) bei Java.lang.reflect.Method.invokeNative (Native Method) bei Java.lang.reflect.Method.invoke (Method.Java : 511) bei com.Android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.Java:784) bei com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:551) bei dalvik.system.NativeSt. main (native Methode) Auslöser: com.facebook.FacebookException: LoginActivity kann nicht mit einem Null-Aufrufpaket aufgerufen werden. Dies kann auftreten, wenn der launchMode des Aufrufers singleInstance ist. at com.facebook.LoginActivity.onResume (LoginActivity.Java:110) at Android.app.Instrumentation.callActivityOnResume (Instrumentation.Java:1236) at Android.app.Activity.performResume (Activity.Java:4613) at Android.app. ActivityThread.performResumeActivity (ActivityThread.Java:2796) ... 12 weitere

Update 2: Ich habe den Code durchgesehen und die Implementierung von startChildActivity gefunden:

public void startChildActivity(String Id, Intent intent) {     
   Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
   if (window != null) {
       mIdList.add(Id);
       setContentView(window.getDecorView()); 
   }    
}

Es verwendet das Flag FLAG_ACTIVITY_CLEAR_TOP. Ich habe versucht, es zu entfernen, aber keine Änderung des Ergebnisses.

Update 3:

https://github.com/facebook/facebook-Android-sdk/blob/master/facebook/src/com/facebook/LoginActivity.Java

Der Facebook-Code verwendet

callingPackage = getCallingPackage();

und

if (callingPackage == null) {
       throw new FacebookException(NULL_CALLING_PKG_ERROR_MSG);
}

http://developer.Android.com/reference/Android/app/Activity.html#getCallingPackage ()

Diese Methode hat einen Hinweis:

Wenn die aufrufende Aktivität kein Ergebnis erwartet (das heißt, sie hat nicht das Formular startActivityForResult (Intent, int) verwendet, das einen Anforderungscode enthält), ist das aufrufende Paket null.

In der Methode startChildActivity verwende ich den getLocalActivityManager (). StartActivity in TabsGroupActivity, der ActivityGroup erweitert, um Tab-Aktivitäten zu verarbeiten. http://developer.Android.com/reference/Android/app/LocalActivityManager.html#startActivity(Java.lang.String, Android.content.Intent)

Diese Methode entspricht nicht den Angaben in den Notizen. Es erwartet kein Ergebnis und verwendet nicht die Methode startActivityForResult. Die Methode stellt auch etwas sicher, das dem SingleInstance-LaunchMode ähnelt. Wie soll ich diese Methodenimplementierung ändern, damit sie mit Facebook funktioniert?

20

Nach langem Suchen stellte ich fest, dass es keine Möglichkeit zu geben scheint, ActiveForResult mit LocalActivityManager zu starten, das in den Registerkarten verwendet wird.

Also habe ich akzeptiert, dass eine Aktivität erforderlich ist, die den gesamten Bildschirm ausfüllt. Die Aktivität wird bei guter Netzwerkverbindung nur etwa eine Sekunde lang angezeigt - ich habe es auch mit einer Neuveröffentlichungsoption für Fehler gemacht.

Veröffentlichungsaktivität starten:

Intent intent = new Intent(this, FacebookShareActivity.class);
intent.putExtra(Constants.FACEBOOK_MESSAGE, shareMessage.getMessage());
startActivityForResult(intent, 1);

Aktivitätscode für Facebook-Freigabe - Veröffentlichung auf der Benutzerwand:

public class FacebookShareActivity extends Activity {
    String message;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.facebook_publishing);

        message = getIntent().getExtras().getString(Constants.FACEBOOK_MESSAGE);
        createFacebookConnection();
    }

    public void republishButton_Click(View view){
        setVisibilityForRepublishButton(false);
        createFacebookConnection();
    }

    public void createFacebookConnection() {
        Session session = new Session(this);
        Session.setActiveSession(session);

        Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);

        Session.StatusCallback statusCallback = new Session.StatusCallback() {
            @Override
            public void call(Session session, SessionState state, Exception exception) {
                String message = "Facebook session status changed - " + session.getState() + " - Exception: " + exception;
                //Toast.makeText(FacebookShareActivity.this, message, Toast.LENGTH_SHORT).show();
                Log.w("Facebook test", message);

                if (session.isOpened() || session.getPermissions().contains("publish_actions")) {
                    publishToWall();
                } else if (session.isOpened()) {
                    OpenRequest open = new OpenRequest(FacebookShareActivity.this).setCallback(this);
                    List<String> permission = new ArrayList<String>();
                    permission.add("publish_actions");
                    open.setPermissions(permission);
                    Log.w("Facebook test", "Open for publish");
                    session.openForPublish(open);
                }
            }
        };

        if (!session.isOpened() && !session.isClosed() && session.getState() != SessionState.OPENING) {
            session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
        } else {
            Log.w("Facebook test", "Open active session");
            Session.openActiveSession(this, true, statusCallback);
        }
    }

    private void setVisibilityForRepublishButton(Boolean visible) {
        ((Button) findViewById(R.id.republishButton)).setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
        //Toast.makeText(FacebookShareActivity.this, "onActivityResult", Toast.LENGTH_SHORT).show();
    }

    void publishToWall() {
        Session session = Session.getActiveSession();

        Bundle postParams = new Bundle();
        postParams.putString("message", message);

        final Context context = this;
        Request.Callback callback = new Request.Callback() {
            public void onCompleted(Response response) {
                FacebookRequestError error = response.getError();
                if (error != null) {
                    setVisibilityForRepublishButton(true);
                    Toast.makeText(context, error.getErrorMessage(), Toast.LENGTH_SHORT).show();
                } else {
                    JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
                    String postId = null;
                    try {
                        postId = graphResponse.getString("id");
                    } catch (JSONException e) {
                        setVisibilityForRepublishButton(true);
                        Log.i("Facebook error", "JSON error " + e.getMessage());
                    }
                    //Toast.makeText(context, postId, Toast.LENGTH_LONG).show();
                    finish();
                }
            }
        };

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

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

Ich habe mein Problem gefunden. Obwohl ich nicht untergegangen bin

Android: launchMode = "singleTask"

meine LoginActivity hatte

Android: noHistory = "true"

was zu dieser Ausnahme führt. Ich habe noHistory auf "true" gesetzt, weil ich nicht wollte, dass der Benutzer bei der ersten Aktivität nach der Anmeldung die Schaltfläche "Zurück" drücken und zum Anmeldebildschirm zurückkehren kann. Jetzt muss ich eine andere Lösung finden.

7

Ich habe das gleiche Problem: Ich versuche, mich über das im SDK bereitgestellte Dialogfeld bei Facebook anzumelden, aber über eine Aktivität, die sich selbst in einer Registerkartengruppe befand. wie ShareActivity oben.

Was ich getan habe, heißt im Grunde startActivityForResult für die übergeordnete Aktivität von ShareActivity (dh ShareGroupActivity), anstatt sie für ShareActivity aufzurufen.

Also 1, fügen Sie dies in ShareGroupActivity hinzu:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    System.out.println("facebook status called");
    super.onActivityResult(requestCode, resultCode, data);
    Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}

2 Sie müssen die Klassensitzung innerhalb des FacebookSDK-Projekts unter src com.facebook ändern

2.1 füge einen Booleschen Member hinzu

public boolean insideTabGroup;

2.2 StartActivityDelegate ändern, das von der Sitzung zum Öffnen der Anmeldung verwendet wird; füge den Booleschen Wert als Parameter hinzu

interface StartActivityDelegate {
    public void startActivityForResult(Intent intent, int requestCode, boolean insideTabGroup);

    public Activity getActivityContext();
}

2.3 Ändern Sie in der inneren Klasse AuthorizationRequest die Implementierung dieses Delegaten:

    AuthorizationRequest(final Activity activity) {
        startActivityDelegate = new StartActivityDelegate() {
            @Override
            public void startActivityForResult(Intent intent, int requestCode, boolean insideTabGroup) {
                if(insideTabGroup) {
                    ActivityGroup parentActivity = (ActivityGroup) activity.getParent();
                    parentActivity.startActivityForResult(intent,requestCode);

                } else {
                    activity.startActivityForResult(intent, requestCode);
                }
            }

            @Override
            public Activity getActivityContext() {
                return activity;
            }
        };
    }

2.4 Ändern Sie auch die anderen Konstruktoren von AuthorizationRequest, indem Sie einfach den booleschen Parameter hinzufügen. Da ich die Anmeldung bei Facebook nicht von einem anderen Ort als einer Aktivität aus verwende, ist das in Ordnung.

2.5 Ändern Sie die tryLoginActivity-Methode der Session-Klasse, um den booleschen Member als Parameter zu verwenden:

private boolean tryLoginActivity(AuthorizationRequest request) {
    Intent intent = getLoginActivityIntent(request);

    if (!resolveIntent(intent)) {
        return false;
    }

    try {
        request.getStartActivityDelegate().startActivityForResult(intent, request.getRequestCode(),this.insideTabGroup);

    } catch (ActivityNotFoundException e) {
        return false;
    }

    return true;
}

3 Legen Sie das Boolesche Element in der Sitzung fest:

Session session = Session.getActiveSession();
session.insideTabGroup = true;

Das sollte den Trick machen.

Cdt

2
Sandro

Ich hatte den gleichen Fehler bei der Parse.com Facebook SDK-Integration und mir fehlte der Aufruf von ParseFacebookUtils.finishAuthentication, der in docs vermerkt ist.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data);
}
0
scottyab