2013-01-02 2 views
20

Ich versuche, einen Android-App mit der neuen Facebook 3.0 api zu integrieren, aber ich bekomme diese Ausnahme:aktualisiert - Android Facebook api 3.0 Fehler: Der Anruf kann nicht LoginActivity mit einem Null-calling Paket

java.lang.RuntimeException: Unable to resume activity {dk.imu.konnekt/com.facebook.LoginActivity}: com.facebook.FacebookException: Cannot call LoginActivity with a null calling package. This can occur if the launchMode of the caller is singleInstance.

Ich habe Suche nach diesem Fehler, aber niemand sonst scheint Probleme damit gehabt zu haben. Ich denke, es ist, weil ich ein TabHost und TabsGroupActivities für jede Registerkarte verwenden. Aber ich habe keine Ahnung, wie ich es lösen kann.

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); 
    } 
} 

keine Ahnung, wie es zu lösen?

Update 1 Stack-Trace:

FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity {dk.imu.konnekt/com.facebook.LoginActivity}: com.facebook.FacebookException: Cannot call LoginActivity with a null calling package. This can occur if the launchMode of the caller is singleInstance. at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2812) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2851) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2234) at android.app.ActivityThread.access$600(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261) at android.os.Handler.dispatchMessage(Handler.java:99) android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:4945) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method) Caused by: com.facebook.FacebookException: Cannot call LoginActivity with a null calling package. This can occur if the launchMode of the caller is singleInstance. 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 more

Update 2: Ich sah den Code durch und die Umsetzung 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 die Flagge FLAG_ACTIVITY_CLEAR_TOP. Ich habe versucht, es zu entfernen, aber keine Veränderung im Ergebnis.

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 eine Notiz:

If the calling activity is not expecting a result (that is it did not use the startActivityForResult(Intent, int) form that includes a request code), then the calling package will be null.

Bei dem Verfahren startChildActivity ich die getLocalActivityManager() verwenden startActivity, in TabsGroupActivity die Activity erstreckt, Registerkarte Aktivitäten zu behandeln.. http://developer.android.com/reference/android/app/LocalActivityManager.html#startActivity(java.lang.String, android.content.Intent)

Diese Methode sagt nicht, was die Notizen sagen. Es erwartet kein Ergebnis und verwendet nicht die startActivityForResult-Methode. Die Methode gewährleistet auch etwas Ähnliches wie der Launchmode singleinstance. Wie soll ich diese Methode Implementierung ändern, so kann es mit Facebook arbeiten?

+0

'die launchMode des Anrufers ist singleInstance' – njzk2

+0

Post voll stacktrace – njzk2

+0

jede SingleInstance Aktivität in das alles? – njzk2

Antwort

5

Nach vielen der Suche dachte ich, dass da draußen scheint nicht ein Weg, um mit LocalActivityManager in den Registerkarten verwendet, um startActivityForResult.

So landete ich zu akzeptieren, dass es eine Aktivität benötigen den gesamten Bildschirm ausfüllt. Die Aktivität wird nur eine Sekunde oder so mit einem guten Netzwerkverbindung gezeigt - ich habe es mit einer Republish Option auf Fehler auch gemacht ..

Start-Aktivität veröffentlichen:

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

Facebook teilen Aktivitätscode - an Benutzer Wand Veröffentlichung:

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(); 
    } 
} 
7

ich es geschafft, mein Problem zu finden. Obwohl ich nicht

android einstellen: launchMode = "singleTask"

meine LoginActivity hatte

android: Nohistory = "true"

, die in dieser Ausnahme führt. Ich habe noHistory auf true gesetzt, weil ich nicht wollte, dass der Benutzer die Taste bei der ersten Aktivität nach der Anmeldung drücken und zurück zum Login-Bildschirm gehen kann. Jetzt muss ich eine andere Lösung finden.

2

Ich habe das gleiche Problem: Ich versuche, mich mit dem Dialog, der im SDK enthalten ist, bei Facebook anzumelden, aber von einer Aktivität, die selbst in einer Tabgruppe war; wie ShareActivity oben.

Was ich getan habe, heißt im Wesentlichen startActivityForResult für die übergeordnete Aktivität von ShareActivity (das ist ShareGroupActivity), anstatt es auf ShareActivity aufzurufen.

So 1, fügen Sie diese in ShareGroupActivity:

@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 Klasse Session ändern, innerhalb FacebookSDK Projekt unter src com.facebook

2.1 fügen Sie ein boolean Mitglied

public boolean insideTabGroup; 

2.2 modifizieren StartActivityDelegate, das von Sitzung verwendet wird, um die Anmeldung zu öffnen; die boolean als Parameter hinzufügen

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

    public Activity getActivityContext(); 
} 

2,3 innerhalb der inneren Klasse AuthorizationRequest, ändern Sie die Umsetzung dieser Delegierten:

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 Auch ändern die anderen Konstrukteure AuthorizationRequest, nur um den Booleschen Parameter hinzufügen. Da ich mich von einem anderen Ort als einer Aktivität nicht bei Facebook anmelde, ist das in Ordnung.

2.5 Modifiy die tryLoginActivity Methode der Klasse Session, die boolean Mitglied 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 Stellen Sie den boolean Mitglied in der Sitzung:

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

, die den Trick tun sollten .

Cdt

+0

das hat mir sehr geholfen! – NadavN7

+0

Danke für die kurze Beschreibung. –

0

Ich hatte den gleichen Fehler mit der Parse.com Facebook SDK Integration und war ich nach unten um den Anruf zu ParseFacebookUtils.finishAuthentication fehle, die in den docs vermerkt ist.

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