【问题标题】:How my app can know when user logout from its Android native Facebook app?我的应用程序如何知道用户何时从其 Android 原生 Facebook 应用程序注销?
【发布时间】:2014-08-19 05:53:14
【问题描述】:

我的应用如何知道用户何时从其原生 Facebook 应用注销?

我在我的应用程序中使用以下代码从 Facebook 注销。它工作正常。

class LogoutTask extends AsyncTask<Void, Void, Void> {

       @Override
       protected Void doInBackground(Void... params) {
            if (facebook.isSessionValid()) {
                try {
                    facebook.logout(getApplicationContext());
                    editLoginStatus(false);
                    SharedPreferences.Editor editor = mPrefs.edit();
                    editor.putString("access_token", null);
                    editor.putLong("access_expires",
                            facebook.getAccessExpires());
                    editor.commit();

                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {

            super.onPostExecute(result);
        }

    }

但是当用户从其原生 Facebook 应用注销然后点击我的应用上的注销按钮时,就会出现问题。

它向我显示以下错误

 java.lang.RuntimeException: An error occured while executing doInBackground()
 at android.os.AsyncTask$3.done(AsyncTask.java:299)
 at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
 at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
 at java.util.concurrent.FutureTask.run(FutureTask.java:137)
 at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
 at java.lang.Thread.run(Thread.java:856)
 Caused by: java.lang.IllegalArgumentException: Invalid context argument
 at android.webkit.CookieSyncManager.createInstance(CookieSyncManager.java:86)
 at com.facebook.internal.Utility.clearCookiesForDomain(Utility.java:319)
 at com.facebook.internal.Utility.clearFacebookCookies(Utility.java:343)
 at com.facebook.Session.closeAndClearTokenInformation(Session.java:798)
 at com.facebook.android.Facebook.logoutImpl(Facebook.java:665)
 at com.facebook.android.Facebook.logout(Facebook.java:642)
 at com.example.animation.StartLoginActivity$LogoutTask.doInBackground(StartLoginActivity.java:328)
 at com.example.animation.StartLoginActivity$LogoutTask.doInBackground(StartLoginActivity.java:1)
 at android.os.AsyncTask$2.call(AsyncTask.java:287)
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

我在下面调用这个函数

if (facebook.getAccessToken() != null && facebook.isSessionValid() == true) {
    new LogoutTask().execute();
}

这里 accessToken 我在本地存储在 sharedPreference 中,所以只要我没有从我的应用程序中注销它就不会为空,但我想在从本机 FB 应用程序注销后facebook.isSessionValid() 应该返回 false 而它是返回 true 。那么如何检查 Facebook 应用程序是否已经注销?

【问题讨论】:

  • 有人对我说,用户注销后,之前的会话就会过时。所以现在我的问题是如何检查会话是否已过时?

标签: android facebook facebook-graph-api facebook-login facebook-sdk-3.14.x


【解决方案1】:

在销毁时,您会清除会话和令牌信息,以便在您从本机应用程序注销时......它将清除其凭据

使用这个

  @Override 
  protected void onDestroy() {

   // TODO Auto-generated method stub
  super.onDestroy();
 Session session = Session.getActiveSession();
 session.closeAndClearTokenInformation();


  }

   public void logoutFromFacebook() {
   mAsyncRunner.logout(this, new RequestListener() {
    @Override
    public void onComplete(String response, Object state) {
        Log.d("Logout from Facebook", response);
        if (Boolean.parseBoolean(response) == true) {
            // User successfully Logged out
        }
    }

    @Override
    public void onIOException(IOException e, Object state) {
    }

    @Override
    public void onFileNotFoundException(FileNotFoundException e,
            Object state) {
    }

    @Override
    public void onMalformedURLException(MalformedURLException e,
            Object state) {
    }

    @Override
    public void onFacebookError(FacebookError e, Object state) {
    }
});
}

试试这个它对我有用..所以它也可以解决你的问题

【讨论】:

  • 我没有使用Session.getActiveSession() 来存储我的会话数据,而是使用facebook.getSession。所以当我在 OnDestroy 中写 facebook.getSession.closeAndClearTokenInformation() 时,它会显示 java.lang.IllegalArgumentException: Invalid context argument 错误。
  • 再次查看我已更新的答案.. 或者您可以参考此网址androidhive.info/2012/03/android-facebook-connect-tutorial
  • 仍然有同样的错误,点击注销按钮时显示Invalid context argument
  • 这个异常是关于传递上下文的问题。所以不要传递“this”,请传递 this.getApplicationContext() 当然,这不是最好的解决方案,但它可以完成工作。跨度>
  • 还是没有运气,我试过了,也只试过getApplicationContext()
【解决方案2】:

尝试检查系统中是否有 Facebook 帐户。

AccountManager accountManager = AccountManager.get(context);
Account[] facebookAccounts = accountManager.getAccountsByType("com.facebook.auth.login");
if (facebookAccounts.length > 0) {
    facebook.logout(getApplicationContext());
    ...
}

是的,代码中包含了硬编码的账户类型,由于原生应用可能发生变化,这有点不可靠,尽管这种变化的概率很小。

别忘了给 Manifest 添加GET_ACCOUNTS 权限。

【讨论】:

  • 如果用户从 Facebook 本地应用程序注销,则会话将过时,但如果他再次从 Facebook 应用程序登录,会话将是不同的,但在此方法中 facebookAccounts.length 将返回 1
【解决方案3】:

嗯...这可能会变得棘手。我猜 isSessionValid 是从 FB API 离线检查的。

从您的情况来看,您似乎仍然需要一次调用 FB 来检查会话是否真的有效。因此,根据您的情况,我的建议是进行简单的 FB API 调用,例如 /me,以检查会话的有效性。

如果会话有效,则手动调用注销 API,否则,您知道 FB 会话已过期/已注销。

希望有所帮助 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多