Обновлено – Android Facebook api 3.0 ошибка: не удается вызвать LoginActivity с нулевым вызывающим пакетом

Я пытаюсь интегрировать приложение Android с новым фейсбуком 3.0 api, но я получаю это исключение:

Java.lang.RuntimeException: Невозможно возобновить действие {dk.imu.konnekt / com.facebook.LoginActivity}: com.facebook.FacebookException: Не удается вызвать LoginActivity с нулевым вызывающим пакетом. Это может произойти, если startMode вызывающего является singleInstance.

У меня есть поиск этой ошибки, но никто другой, похоже, не обманывал ее. Я предполагаю, что это потому, что я использую 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 трассировку стека:

FATAL EXCEPTION: main java.lang.RuntimeException: не удается возобновить действие {dk.imu.konnekt / com.facebook.LoginActivity}: com.facebook.FacebookException: не удается вызвать LoginActivity с нулевым вызывающим пакетом. Это может произойти, если startMode вызывающего является singleInstance. На android.app.ActivityThread.performResumeActivity (ActivityThread.java:2812) на android.app.ActivityThread.handleResumeActivity (ActivityThread.java:2851) на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2234) на android.app. ActivityThread.access $ 600 (ActivityThread.java:139) в android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1261) в android.os.Handler.dispatchMessage (Handler.java:99) android.os.Looper.loop (Looper.java:154) в android.app.ActivityThread.main (ActivityThread.java:4945) в java.lang.reflect.Method.invokeNative (собственный метод) в java.lang.reflect.Method.invoke (Method.java : 511) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:784) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:551) в dalvik.system.NativeStart. Main (Native Method) Вызывается: com.facebook.FacebookException: Не удается вызвать LoginActivity с нулевым вызывающим пакетом. Это может произойти, если startMode вызывающего является singleInstance. На com.facebook.LoginActivity.onResume (LoginActivity.java:110) на android.app.Instrumentation.callActivityOnResume (Instrumentation.java:1236) на android.app.Activity.performResume (Activity.java:4613) на android.app. ActivityThread.performResumeActivity (ActivityThread.java:2796) … еще 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

Используется код Facebook

 callingPackage = getCallingPackage(); 

а также

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

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

Этот метод имеет примечание:

Если вызывающая активность не ожидает результата (то есть она не использует форму startActivityForResult (Intent, int), которая включает код запроса), тогда вызывающий пакет будет иметь значение null.

В методе startChildActivity я использую getLocalActivityManager (). StartActivity, в TabsGroupActivity, который расширяет ActivityGroup, для обработки действий с вкладками. Http://developer.android.com/reference/android/app/LocalActivityManager.html#startActivity(java.lang.String, android.content.Intent)

Этот метод не соответствует тем, что написано в заметках. Он не ожидает результата и не использует метод startActivityForResult. Этот метод также обеспечивает нечто похожее на одномоментный запуск. Как мне изменить эту реализацию метода, чтобы она могла работать с facebook?

Мне удалось найти свою проблему. Хотя я не устанавливал

андроид: launchMode = "singleTask"

Моя LoginActivity

андроид: noHistory = "истина"

Что приводит к этому исключению. Я положил noHistory true, потому что я не хотел, чтобы пользователь мог нажать кнопку в первой активности после входа в систему и вернуться к экрану входа в систему. Теперь мне нужно найти другое решение.

После многих поисков я понял, что, похоже, не существует метода startActivityForResult с LocalActivityManager, который используется на вкладках.

Поэтому я пришел к выводу, что для этого потребуется занятие, заполняющее весь экран. Активность показывается только на секунду или около того с хорошим сетевым подключением. Я также сделал это с опцией republish на ошибках.

Начать публикацию деятельности:

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

Код обмена акций Facebook – публикация на стене пользователей:

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

У меня такая же проблема: попытка войти в facebook с диалогом, представленным внутри SDK, но из активности, которая сама была внутри tabgroup; Как ShareActivity выше.

То, что я сделал, в основном называется startActivityForResult для родительской активности ShareActivity (это ShareGroupActivity), вместо того, чтобы называть его в ShareActivity.

Итак, добавьте это в 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 вам необходимо изменить сеанс класса, в рамках проекта FacebookSDK, в разделе src com.facebook

2.1 добавить логический элемент

 public boolean insideTabGroup; 

2.2 изменить StartActivityDelegate, который используется сессией для открытия входа; Добавить boolean как параметр

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

2.3 внутри внутреннего класса AuthorizationRequest, измените реализацию этого делегата:

  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, просто добавив логический параметр. Поскольку я не использую login для facebook где-то еще, кроме активности, все в порядке.

2.5. Модифицируйте метод tryLoginActivity класса Session, чтобы использовать логический элемент в качестве параметра:

 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

У меня была такая же ошибка с интеграцией SDK Parse.com Facebook, и мне не хватало вызова ParseFacebookUtils.finishAuthentication который отмечен в документах .

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