【问题标题】:Cant get Facebook Graph API information through access token on android无法通过 android 上的访问令牌获取 Facebook Graph API 信息
【发布时间】:2012-10-23 21:00:29
【问题描述】:

我正在 android 上编写一个简单的应用程序来获取通过 Facebook 登录该应用程序的用户的信息。这是我的代码:

public class example extends Activity {

Facebook facebook = new Facebook("id");
AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);

private static final String TAG ="Debug";
private SharedPreferences mPrefs;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_example);
    /*
     * Get existing access_token if any
     */
    mPrefs = getPreferences(MODE_PRIVATE);
    String access_token = mPrefs.getString("access_token", null);
    long expires = mPrefs.getLong("access_expires", 0);
    if(access_token != null) {
        facebook.setAccessToken(access_token);
    }
    if(expires != 0) {
        facebook.setAccessExpires(expires);
    }

    /*
     * Only call authorize if the access_token has expired.
     */
    if(!facebook.isSessionValid()) {

        facebook.authorize(this, new String[] {"publish_stream","email","user_groups","read_stream","user_about_me","offline_access"}, new DialogListener() {
            @Override
            public void onComplete(Bundle values) {
                SharedPreferences.Editor editor = mPrefs.edit();
                editor.putString("access_token", facebook.getAccessToken());
                editor.putLong("access_expires", facebook.getAccessExpires());
                editor.commit();
            }

            @Override
            public void onFacebookError(FacebookError error) {}

            @Override
            public void onError(DialogError e) {}

            @Override
            public void onCancel() {}
        });
    }        
    Log.d(TAG, access_token);
    getInformation();
}

private void getInformation(){

    JSONObject json = null;

    try
    {
        Log.d("testing", "point1");
        String response = facebook.request("me");
        Log.d("testing", "point2");
        json = Util.parseJson(response);
        String id = json.getString("id");
        Log.d("testing", id);
    }
    catch (MalformedURLException e)
    {
        e.printStackTrace();
    }
    catch (JSONException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    catch (FacebookError e)
    {
        e.printStackTrace();
    }

}

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

    facebook.authorizeCallback(requestCode, resultCode, data);
}

@Override
public void onResume() {    
    super.onResume();
    facebook.extendAccessTokenIfNeeded(this, null);
}
}

我在这里关注https://developers.facebook.com/docs/mobile/android/build/#sdk 并使用相同的 facebook SDK。因此,如代码所示,在 logcat 中只有 point1 而不是 point2,这意味着 facebook.request("me") 不成功。模拟器显示应用程序关闭并说“不幸的是,示例已停止。”

那么谁能帮我指出这个问题?我想知道访问令牌中是否有问题,但我不知道。非常感谢。

LogCat:

11-03 10:13:55.986: D/Debug(893): AAAFi20EvlJEBACwBLIR4buSOaZB1emxACFPZCZAKums6ZCNwZB0wZCvQnI3grshT0YNl8ZC427BSkrNye6akdCZBjvp4KL24Oyx......
11-03 10:13:55.986: D/testing(893): point1
11-03 10:13:56.106: D/AndroidRuntime(893): Shutting down VM
11-03 10:13:56.106: W/dalvikvm(893): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
11-03 10:13:56.136: E/AndroidRuntime(893): FATAL EXCEPTION: main
11-03 10:13:56.136: E/AndroidRuntime(893): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.crush/com.example.crush.Crush}: android.os.NetworkOnMainThreadException
11-03 10:13:56.136: E/AndroidRuntime(893):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)

【问题讨论】:

  • 请发布您的 logcat 输出

标签: android facebook-graph-api access-token


【解决方案1】:

您正在主线程上运行网络操作。使用异步任务在后台线程中运行网络操作(在后台线程中执行您的 http 请求)。这就是您收到 android.os.NetworkOnMainThreadException 的原因。

像这样在异步任务中建立网络:

class FacebookRequestTask extends AsyncTask{


    protected void onPreExecute() {
    //show a progress dialog to the user or something
    }

    protected void doInBackground() {
        //Do your networking here
    }

    protected void onPostExecute() {
        //do something with your parsed 
        //response (JSON data in case of facebook API's) here 
        // and dismiss the progress dialog
    }
  }

  new facebookRequestTask().execute();

如果您不知道如何使用异步任务,这里有一些教程供您参考:

http://mobileorchard.com/android-app-developmentthreading-part-2-async-tasks/

http://www.vogella.com/articles/AndroidPerformance/article.html

以下是来自 Google 的官方文档:

https://developer.android.com/reference/android/os/AsyncTask.html

【讨论】:

  • 非常感谢。但是,有没有其他方法可以做到这一点但更容易?我可以只在主线程上运行它吗?
  • 没有。由于网络操作会导致 UI 线程阻塞,Android 已禁用此功能。唯一的另一种方法是使用自己的线程实现,这绝对不是一件容易的事。
  • 非常感谢。我发现另一个解决这个问题的方法是: if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);我可以解决这个问题并在模拟器中工作,但不能在 SIII 上工作(我对其进行了签名并在其上安装了 apk)。此应用在打开几秒钟后关闭,我想知道是不是这个问题引起的。
  • 那么,你能告诉我更多关于编码的信息吗?这个类可以只放在main.Java中吗?我的代码的哪一部分应该在 doInBackground() 中,哪一部分应该在 onPostExecute() 中?对不起,我是 OOP 和 Java 的初学者,再次感谢。
  • 不要使用该修复程序。这不是真正的修复,而只是一个补丁代码。始终在后端建立网络。仔细阅读我提供链接的教程。试试看。如果之后有更多疑问,您可以随时回来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
相关资源
最近更新 更多