android एंड्रॉइड फेसबुक एपीआई 3.0 त्रुटि: एक नल कॉलिंग पैकेज के साथ LoginActivity को कॉल नहीं कर सकता




मेरा फोन क्यों नहीं लग रहा है (4)

मैं नए फेसबुक 3.0 एपीआई के साथ एक एंड्रॉइड ऐप को एकीकृत करने की कोशिश कर रहा हूं, लेकिन मुझे यह अपवाद मिलता है:

java.lang.RuntimeException: गतिविधि को फिर से शुरू करने में असमर्थ {dk.imu.konnekt / com.facebook.LoginActivity}: com.facebook.FacebookException: एक शून्य कॉलिंग पैकेज के साथ LoginActivity को कॉल नहीं कर सकता। ऐसा तब हो सकता है जब कॉलर का लॉन्चमोड एकलInstance है।

मैंने इस त्रुटि की खोज की है लेकिन किसी और के साथ कोई ट्रोबल नहीं हुआ है। मुझे लगता है कि ऐसा इसलिए है क्योंकि मैं प्रत्येक टैब के लिए TabHost और TabsGroupActivities का उपयोग कर रहा हूं। लेकिन मुझे इसका समाधान करने के बारे में कोई जानकारी नहीं है।

मैंने यहां प्रासंगिक कोड जोड़ा है:

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

इसे हल करने के तरीके पर कोई सुराग?

1 स्टैक ट्रेस अपडेट करें:

अंतिम अपवाद: मुख्य java.lang.RuntimeException: गतिविधि को फिर से शुरू करने में असमर्थ {dk.imu.konnekt / com.facebook.LoginActivity}: com.facebook.FacebookException: एक शून्य कॉलिंग पैकेज के साथ लॉगिन एक्टिविटी को कॉल नहीं कर सकता। ऐसा तब हो सकता है जब कॉलर का लॉन्चमोड एकलInstance है। android.app.ActivityThread.performResumeActivity (ActivityThread.java:2812) android.app.ActivityThread.handleResumeActivity (ActivityThread.java22851) atroid.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2234) atroid.app पर। AndroidThread.access $ 600 (ActivityThread.java:139) atroid.app.ActivityThread $ H.handleMessage (ActivityThread.java:1261) android.os.Handler.dispatchMessage (Handler.java:99) android.os.Looper.loop पर (Looper.java:154) java.lang.refang.Method.invoke (method.java) पर java.lang.reflect.Method.invokeNative (मूल विधि) पर android.app.ActivityThread.main (ActivityThread.java:4945) पर। : 511) com.android.internal.os.ZygoteInit $ methodAndArgsCaller.run (ZygoteInit.java:784) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:5251) पर dalvik.system.NativeStart पर। मुख्य (मूल विधि) के कारण: com.facebook.FacebookException: एक शून्य कॉलिंग पैकेज के साथ LoginActivity को कॉल नहीं कर सकता। ऐसा तब हो सकता है जब कॉलर का लॉन्चमोड एकलInstance है। com.facebook.LoginActivity.onResume (LoginActivity.java:110) पर android.app.Instrumentation.callActivityOnResume (Instrumentation.java:1236) atroid.app.Activity.performResume (Activity.java:4613) atroid.app पर। ActivityThread.performResumeActivity (ActivityThread.java's796) ... 12 और

अद्यतन 2: मैंने कोड को देखा और startChildActivity के कार्यान्वयन को पाया:

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

यह ध्वज FLAG_ACTIVITY_CLEAR_TOP का उपयोग करता है। मैंने इसे हटाने की कोशिश की, लेकिन परिणाम में कोई बदलाव नहीं आया।

अद्यतन 3:

https://github.com/facebook/facebook-android-sdk/blob/master/facebook/src/com/facebook/LoginActivity.java

फेसबुक कोड का उपयोग करता है

callingPackage = getCallingPackage();

तथा

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

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

इस विधि में एक नोट है:

यदि कॉलिंग गतिविधि किसी परिणाम की अपेक्षा नहीं कर रही है (यानी यह startActivityForResult (इरादा, int) फ़ॉर्म का उपयोग नहीं करता है जिसमें एक अनुरोध कोड शामिल है), तो कॉलिंग पैकेज शून्य हो जाएगा।

विधि में प्रारंभ करें ChildActivity मैं टैब गतिविधियों को संभालने के लिए, गतिविधि समूह को विस्तारित करता हूं, टैबस समूह एक्टिविटी में getLocalActivityManager ()। StartActivity का उपयोग करता हूं। http://developer.android.com/reference/android/app/LocalActivityManager.html#startActivity(java.lang.String, android.content.Intent)

यह विधि नोट्स कहती नहीं है। यह परिणाम की अपेक्षा नहीं करता है और startActivityForResult विधि का उपयोग नहीं करता है। विधि सिंगलइंस्टेंस लॉन्चमोड के समान कुछ भी सुनिश्चित करता है। मुझे इस विधि कार्यान्वयन को कैसे बदलना चाहिए, इसलिए यह फेसबुक के साथ काम कर सकता है?


बहुत सारी खोजों के बाद मुझे पता चला कि स्थानीय एक्टिविटी मैनेजर टैब के साथ एक्टिविटीफॉर रिसेट शुरू करने का तरीका नहीं लगता है।

इसलिए मैंने स्वीकार कर लिया कि उसे पूरी स्क्रीन भरने की गतिविधि की आवश्यकता होगी। गतिविधि केवल एक अच्छा या तो अच्छा नेटवर्क कनेक्शन के साथ दिखाया गया है - मैंने इसे त्रुटियों पर एक पुन: प्रकाशित विकल्प के साथ भी बनाया है ..

गतिविधि प्रकाशित करना प्रारंभ करें:

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

फेसबुक शेयर गतिविधि कोड - उपयोगकर्ताओं की दीवार पर प्रकाशन:

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

मैं अपनी समस्या ढूंढने में कामयाब रहा। हालांकि मैं सेटिंग नहीं कर रहा था

एंड्रॉयड: launchMode = "singleTask"

मेरी लॉगिन एक्टिविटी थी

एंड्रॉयड: noHistory = "true"

जिसके परिणामस्वरूप अपवाद होता है। मैंने कोई इतिहास सही नहीं किया क्योंकि मैं नहीं चाहता था कि उपयोगकर्ता लॉगिन के बाद पहली गतिविधि पर वापस बटन दबाए और लॉगिन स्क्रीन पर वापस जा सके। अब मुझे एक और समाधान खोजने की जरूरत है।


मुझे Parse.com फेसबुक एसडीके एकीकरण के साथ यह वही त्रुटि थी और मेरे पास ParseFacebookUtils.finishAuthentication कॉल खो गया था जो docs में नोट किया गया है।

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

मुझे एक ही समस्या है: एसडीके के अंदर दिए गए संवाद के साथ, फेसबुक में लॉग इन करने का प्रयास कर रहा है, लेकिन एक गतिविधि से जो स्वयं एक टैबग्रुप के अंदर था; ऊपर शेयरएक्टिविटी की तरह।

मैंने जो किया है उसे मूल रूप से ShareActivity (जिसे ShareGroupActivity है) की मूल गतिविधि पर StartActivityForResult कहा जाता है, इसे ShareActivity पर कॉल करने के बजाय।

तो 1, इसे 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 आपको src com.facebook के तहत, फेसबुक एसडीके प्रोजेक्ट के अंदर कक्षा सत्र को संशोधित करने की आवश्यकता है

2.1 एक बुलियन सदस्य जोड़ें

public boolean insideTabGroup;

2.2 StartActivityDelegate को संशोधित करें, जिसका उपयोग सत्र खोलने के लिए सत्र द्वारा किया जाता है; बूलियन को पैरामीटर के रूप में जोड़ें

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

    public Activity getActivityContext();
}

2.3 आंतरिक वर्ग प्राधिकरण के भीतर, इस प्रतिनिधि के कार्यान्वयन को संशोधित करें:

    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 इसके अलावा, बूलियन पैरामीटर जोड़कर, AuthorizationRequest के अन्य रचनाकारों को संशोधित करें। चूंकि मैं किसी गतिविधि से कहीं और फेसबुक से लॉगिन का उपयोग नहीं करता, यह ठीक है।

2.5 मॉड्यूलियस सत्र वर्ग की tryLoginActivity विधि, बूलियन सदस्य को पैरामीटर के रूप में उपयोग करने के लिए:

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 सत्र में बूलियन सदस्य सेट करें:

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

यह ट्रिक काम आना चाहिए।

CDT





tabactivity