Facebook 登录按钮导致崩溃

Posted

技术标签:

【中文标题】Facebook 登录按钮导致崩溃【英文标题】:Facebook login button causes a crash 【发布时间】:2015-12-06 16:24:49 【问题描述】:

我在尝试将 Facebook 登录按钮作为 android 应用程序的一部分时遇到问题。

应用程序启动良好,但当我按下 Facebook 登录按钮时它崩溃了。

这是它在日志中所说的:

12-06 17:17:01.079 25678-25678/com.example.icen.tij01 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                 Process: com.example.icen.tij01, PID: 25678
                                                                                 java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.Fragment com.facebook.internal.FragmentWrapper.getSupportFragment()' on a null object reference
                                                                                     at com.facebook.FacebookButtonBase.getFragment(FacebookButtonBase.java:105)
                                                                                     at com.facebook.login.widget.LoginButton$LoginClickListener.onClick(LoginButton.java:736)
                                                                                     at com.facebook.FacebookButtonBase$1.onClick(FacebookButtonBase.java:383)
                                                                                     at android.view.View.performClick(View.java:5198)
                                                                                     at android.view.View$PerformClick.run(View.java:21147)
                                                                                     at android.os.Handler.handleCallback(Handler.java:739)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                     at android.os.Looper.loop(Looper.java:148)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-06 17:17:03.055 25678-25678/com.example.icen.tij01 I/Process: Sending signal. PID: 25678 SIG: 9

更新:

这是必须处理 Facebook 登录的 Activity 的一部分:

package com.example.icen.tij01;

import android.app.Activity;
/* import... */

public class StartActivity extends ActionBarActivity 

    static String hostDomain = "http://192.168.48.1/myphpApp/";

    private TextView info;
    private LoginButton loginButton;
    private CallbackManager callbackManager;

    static String checkUrl = hostDomain + "connect.php";

    String responseServer;


    @Override
    protected void onCreate(Bundle savedInstanceState) 

        super.onCreate(savedInstanceState);

        FacebookSdk.sdkInitialize(getApplicationContext());
        callbackManager = CallbackManager.Factory.create();

        setContentView(R.layout.activity_start);


        info = (TextView)findViewById(R.id.info);
        loginButton = (LoginButton)findViewById(R.id.login_button);

        // redirekicija na formu za logovanje
        Button btnLogin = (Button) findViewById(R.id.btnLogin);
        btnLogin.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                Intent loginForm = new Intent(StartActivity.this, LoginFormActivity.class);
                startActivity(loginForm);
            
        );

        loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() 
            @Override
            public void onSuccess(LoginResult loginResult) 
                info.setText(
                        "User ID: "
                                + loginResult.getAccessToken().getUserId()
                                + "\n" +
                                "Auth Token: "
                                + loginResult.getAccessToken().getToken()
                );
            

            @Override
            public void onCancel() 
                info.setText("Login attempt canceled.");
            

            @Override
            public void onError(FacebookException e) 

            

        );

    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        callbackManager.onActivityResult(requestCode, resultCode, data);
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_start, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) 
            return true;
        

        return super.onOptionsItemSelected(item);
    




    /* Inner class to get response */
    class AsyncT extends AsyncTask<Void, Void, Void> 
        @Override
        protected Void doInBackground(Void... voids) 
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(checkUrl);

            try 
                JSONObject jsonobj = new JSONObject();
                jsonobj.put("name", "Aneh");
                jsonobj.put("age", "22");

                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("req", jsonobj.toString()));

                Log.e("mainToPost", "mainToPost" + nameValuePairs.toString());

                // Use UrlEncodedFormEntity to send in proper format which we need
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                // Execute HTTP Post Request
                HttpResponse response = httpclient.execute(httppost);
                InputStream inputStream = response.getEntity().getContent();
                InputStreamToStringExample str = new InputStreamToStringExample();
                responseServer = str.getStringFromInputStream(inputStream);

                //Log.e("response", "response -----" + responseServer);


             catch (Exception e) 
                e.printStackTrace();
            
            return null;
        

        @Override
        protected void onPostExecute(Void aVoid) 
            super.onPostExecute(aVoid);

            Context context = getApplicationContext();
            int duration = Toast.LENGTH_SHORT;
            Toast toast;

            if(responseServer.trim().equals("1")) 

                toast = Toast.makeText(context, "Connection ok, redirecting to adverts...", duration);
                toast.show();
                Intent show = new Intent(StartActivity.this, MainActivity.class);
                startActivity(show);

             else 
                toast = Toast.makeText(context, "Connection error", duration);
                toast.show();

                AlertDialog alertDialog = new AlertDialog.Builder(StartActivity.this).create();
                alertDialog.setTitle("Connection error");
                alertDialog.setMessage("Error. Please check your connection");
                alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                        new DialogInterface.OnClickListener() 
                            public void onClick(DialogInterface dialog, int which) 
                                dialog.dismiss();
                            
                        );
                alertDialog.show();

            


        
    



    public static class InputStreamToStringExample 

        public static void main(String[] args) throws IOException 

            // intilize an InputStream
            InputStream is =
                    new ByteArrayInputStream("file content..blah blah".getBytes());

            String result = getStringFromInputStream(is);

            System.out.println(result);
            System.out.println("Done");

        

        // convert InputStream to String
        private static String getStringFromInputStream(InputStream is) 

            BufferedReader br = null;
            StringBuilder sb = new StringBuilder();

            String line;
            try 

                br = new BufferedReader(new InputStreamReader(is));
                while ((line = br.readLine()) != null) 
                    sb.append(line);
                

             catch (IOException e) 
                e.printStackTrace();
             finally 
                if (br != null) 
                    try 
                        br.close();
                     catch (IOException e) 
                        e.printStackTrace();
                    
                
            
            return sb.toString();
        

    




我遵循了几个教程,例如:

http://code.tutsplus.com/tutorials/quick-tip-add-facebook-login-to-your-android-app--cms-23837

你能帮我解决这个问题吗?

【问题讨论】:

你能显示StartActivity的完整代码吗?你在你的活动中加入了onActivityResult()吗? 是的,我的活动中有 onActivityResult()。您现在可以查看我的帖子吗,它已更新完整的活动代码 对于 facebook 集成,我们必须检查所有 gradle、manifest、xml 和 startactivity 文件。如果您在单击 FBLogin 按钮时遇到空指针异常,则意味着您没有在清单中正确集成 com.facebook.FacebookActivity,或者在获取 AppId 时 Facebook 集成可能存在错误。我将附上正确的工作链接 Android Studio Facebook Integration 检查它。 【参考方案1】:

问题在于 facebook 登录按钮。由于某种原因,它没有被初始化。 我尝试了很多不同的方法来解决这个问题。最后得到了两个解决方案。

1) 更改您的类以扩展 fragment.And setFragment 到您的 fb_login_button 根据 https://developers.facebook.com/docs/facebook-login/android

  
     loginButton = (LoginButton) view.findViewById(R.id.login_button);
     loginButton.setReadPermissions("user_friends");
     loginButton.setFragment(this); 
  

2) 代替 facebook_login_button 创建一个自定义按钮。 并在 onClickListener 上调用具有 callBackManager 和 LoginManager 的方法。

login_activity 中的自定义按钮

    <Button
        android:id="@+id/fb_btn"
        android:layout_
        android:layout_
        android:layout_gravity="center"
        android:background = "@drawable/btn_facebook"
        />

登录_活动

        fb_btn = (Button) findViewById(R.id.fb_btn);

        fb_btn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 

                onfbClick();
            

        );

调用LoginManager的方法

    private void onfbClick() 
    callbackManager = CallbackManager.Factory.create();

    LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email","public_profile"));
    LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() 
        @Override
        public void onSuccess(LoginResult loginResult) 
            // App code
            accessToken = loginResult.getAccessToken();
            Profile profile = Profile.getCurrentProfile();

            Bundle parameters = new Bundle();
            parameters.putString("fields", "first_name,last_name");
            //request.setParameters(parameters);
            //request.executeAsync();
        

        @Override
        public void onCancel() 
            Log.i(TAG, "onCancel triggered");
        

        @Override
        public void onError(FacebookException exception) 
            Log.i(TAG, "onError triggered");

        
    );


【讨论】:

【参考方案2】:

当 Fragment 被调用时,很难看出在哪里或为什么会出现空指针异常,这也是因为它是一个自定义示例。

我建议你试试Simple Facebook,它会让你在 Facebook 的生活更轻松。

【讨论】:

以上是关于Facebook 登录按钮导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

React Native Facebook 登录按钮在 iOS 模拟器中使应用程序崩溃

使用 facebook connect 登录后应用程序崩溃

取消 Google Play 游戏登录后 Facebook 登录崩溃(反之亦然)

登录onActivityResult Android后Facebook SDK应用程序崩溃

初始化 Facebook 实用程序

适用于 iOS 的 Xamarin facebook sdk 导致应用程序崩溃