Android 在登录中未包含的函数上解析FB登录崩溃

Android 在登录中未包含的函数上解析FB登录崩溃,android,facebook,parse-platform,nullpointerexception,facebook-login,Android,Facebook,Parse Platform,Nullpointerexception,Facebook Login,我集成了Parse登录(v1.10.3),在集成FB登录(v4.8.2)之前,我从未遇到过这个问题。如果卸载并重新安装应用程序并启动,当应用程序启动时,我会收到登录后发生的活动的错误。我将MainActivity作为启动页面,它会检查当前用户。如果当前用户为空,则会重定向到LoginActivity。LoginActivity崩溃,在链接到从主适配器调用的片段的适配器中发生空指针异常错误。为什么要跳过我的登录活动 我的代码中有很多日志,因为我试图确定在某个点上是否存在当前用户值,或者是否执行了任

我集成了Parse登录(v1.10.3),在集成FB登录(v4.8.2)之前,我从未遇到过这个问题。如果卸载并重新安装应用程序并启动,当应用程序启动时,我会收到登录后发生的活动的错误。我将MainActivity作为启动页面,它会检查当前用户。如果当前用户为空,则会重定向到LoginActivity。LoginActivity崩溃,在链接到从主适配器调用的片段的适配器中发生空指针异常错误。为什么要跳过我的登录活动

我的代码中有很多日志,因为我试图确定在某个点上是否存在当前用户值,或者是否执行了任何登录函数,这会导致它跳过登录,但没有执行任何一个,并且当前用户始终为Null(我预期)

登录活动

public static final List<String> mPermissions = new ArrayList<String>() {
    {
        add("public_profile");
        add("email");
        add("gender");
        add("user_birthday");
    }};



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    //set and transition to signup page
    mSignUpTextView = (TextView)findViewById(R.id.signupText);
    mSignUpTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(LoginActivity.this, SignupActivity.class);
            startActivity(intent);
        }
    });

    //set and transition to reset password page
    mResetPasswordText = (TextView)findViewById(R.id.login_ForgotPasswordText);
    mResetPasswordText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(LoginActivity.this, ResetPasswordActivity.class);
            startActivity(intent);
        }
    });

    //set and handle all login tasks
    mUsername = (EditText)findViewById(R.id.usernameField);
    mPassword = (EditText)findViewById(R.id.passwordField);
    mLoginButton = (Button)findViewById(R.id.loginButton);

    //Facebook login
    loginButton = (LoginButton) findViewById(R.id.login_button);
    loginButton.setReadPermissions(Arrays.asList("public_profile, email, user_birthday, user_friends"));

    callbackManager = CallbackManager.Factory.create();


    mFbProfile = Profile.getCurrentProfile();
    Log.d("Login FB", String.valueOf(mFbProfile));


    // Other app specific specialization

    // Callback registration
    loginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            ParseFacebookUtils.logInWithReadPermissionsInBackground(LoginActivity.this, mPermissions, new LogInCallback() {
                @Override
                public void done(ParseUser user, ParseException err) {

                    if (user == null) {
                        Log.d("Login", "Uh oh. The user cancelled the Facebook login.");
                        if (err != null) {
                            Log.d("ParseFacebookLogin", "Error: " + err.getLocalizedMessage());
                        }
                    }
                    else if (user.isNew()) {
                        Log.d("Login", "User signed up and logged in through Facebook!");
                        getUserDetailsFromFB();

                        //success
                        FlokkApp.updateParseInstallation(user);

                        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivity(intent);

                        Log.d("Login FB", "User logged in through Facebook!");

                    }
                    else {
                        Log.d("Login", "User logged in through Facebook!");
                        getUserDetailsFromParse();

                        //success
                        FlokkApp.updateParseInstallation(user);

                        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivity(intent);
                    }
                }
            });

        }
    });





    //Regular Parse Login ----------------------------------------------------------
    mLoginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            String username = mUsername.getText().toString();
            String password = mPassword.getText().toString();

            username = username.trim();
            password = password.trim();

            //noinspection StatementWithEmptyBody
            if (username.isEmpty() || password.isEmpty()){
                // display message if field is blank
                AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
                builder.setMessage(R.string.login_error_message)
                        .setTitle(R.string.login_error_title)
                        .setPositiveButton(android.R.string.ok, null);
                AlertDialog dialog = builder.create();
                dialog.show();
            }
            else {
                // login user
                ParseUser.logInInBackground(username, password, new LogInCallback() {
                    public void done(ParseUser user, ParseException e) {
                        if (user != null) {
                            //success
                            FlokkApp.updateParseInstallation(user);

                            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                            startActivity(intent);
                            //Toast.makeText(LoginActivity.this, "Successful Login", Toast.LENGTH_SHORT).show();
                        }
                        else {
                            AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
                            builder.setMessage(e.getMessage())
                                    .setTitle(R.string.login_error_title)
                                    .setPositiveButton(android.R.string.ok, null);
                            AlertDialog dialog = builder.create();
                            dialog.show();
                        }
                    }
                });
            }

        }
    });
}

//Facebook login required below ------------------------------------
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("Login", "on activity result");

    super.onActivityResult(requestCode, resultCode, data);
    ParseFacebookUtils.onActivityResult(requestCode, resultCode, data);
}

//Facebook save new user code -----------------------------------------------
private void saveNewUser() {
    Log.d("Login", "Save new user");


    parseUser = ParseUser.getCurrentUser();
    parseUser.setUsername(name);
    parseUser.setEmail(email);

    //will need to update once I figure out how facebook sends the data
    boolean genderValue;

    if (gender == "Male") {
        genderValue = true;
    } else {
        genderValue = false;
    };
    parseUser.put(ParseConstants.KEY_GENDERMALE, genderValue);

    String searchtext = name.toLowerCase().trim();
    parseUser.put(ParseConstants.KEY_SEARCHTEXT, searchtext);


    //Saving profile photo as a ParseFile
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    Bitmap bitmap = null; //((BitmapDrawable) mProfileImage.getDrawable()).getBitmap();

    if (bitmap != null) {
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
        byte[] data = stream.toByteArray();
        String thumbName = parseUser.getUsername().replaceAll("\\s+", "");
        final ParseFile parseFile = new ParseFile(thumbName + "_android_FBLogin.jpg", data);

        parseFile.saveInBackground(new SaveCallback() {
            @Override
            public void done(ParseException e) {
                parseUser.put(ParseConstants.KEY_PROFILEPIC, parseFile);

                //Finally save all the user details
                parseUser.saveInBackground(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        Toast.makeText(LoginActivity.this, "New user:" + name + " Signed up", Toast.LENGTH_SHORT).show();
                    }
                });

            }
        });
    }

}

private void getUserDetailsFromFB() {
    Log.d("Login", "getUserDetails From FB");

    // Suggested by https://disqus.com/by/dominiquecanlas/
    Bundle parameters = new Bundle();
    parameters.putString("fields", "email,name,gender,picture");


    new GraphRequest(
            AccessToken.getCurrentAccessToken(),
            "/me",
            parameters,
            HttpMethod.GET,
            new GraphRequest.Callback() {
                public void onCompleted(GraphResponse response) {
                    /* handle the result */
                    try {

                        Log.d("Response", response.getRawResponse());

                        email = response.getJSONObject().getString("email");
                        //mEmailID.setText(email);

                        name = response.getJSONObject().getString("name");
                        mUsername.setText(name);

                        gender = response.getJSONObject().getString("gender");

                        JSONObject picture = response.getJSONObject().getJSONObject("picture");
                        JSONObject data = picture.getJSONObject("data");

                        //  Returns a 50x50 profile picture
                        String pictureUrl = data.getString("url");

                        Log.d("Profile pic", "url: " + pictureUrl);

                        new ProfilePhotoAsync(pictureUrl).execute();

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
    ).executeAsync();

}

private void getUserDetailsFromParse() {
    Log.d(" Login", "getUserDetails From parse");

    parseUser = ParseUser.getCurrentUser();

    //Fetch profile photo
    try {
        ParseFile parseFile = parseUser.getParseFile(ParseConstants.KEY_PROFILEPIC);
        byte[] data = parseFile.getData();
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        //mProfileImage.setImageBitmap(bitmap);

    } catch (Exception e) {
        e.printStackTrace();
    }

    //mEmailID.setText(parseUser.getEmail());
    mUsername.setText(parseUser.getUsername());

    //Toast.makeText(LoginActivity.this, "Welcome back " + mUsername.getText().toString(), Toast.LENGTH_SHORT).show();

}

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

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


//Required for facebook
class ProfilePhotoAsync extends AsyncTask<String, String, String> {
    public Bitmap bitmap;
    String url;

    public ProfilePhotoAsync(String url) {
        this.url = url;
    }

    @Override
    protected String doInBackground(String... params) {
        // Fetching data from URI and storing in bitmap
        bitmap = DownloadImageBitmap(url);
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        //mProfileImage.setImageBitmap(bitmap);

        saveNewUser();
    }
}

public static Bitmap DownloadImageBitmap(String url) {
    Bitmap bm = null;
    try {
        URL aURL = new URL(url);
        URLConnection conn = aURL.openConnection();
        conn.connect();
        InputStream is = conn.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        bm = BitmapFactory.decodeStream(bis);
        bis.close();
        is.close();
    } catch (IOException e) {
        Log.e("IMAGE", "Error getting bitmap", e);
    }
    return bm;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ParseAnalytics.trackAppOpened(getIntent());

    ParseUser currentUser = ParseUser.getCurrentUser();
    if (currentUser == null) {
        navigateToLogin();
        Log.d("Login Check", String.valueOf(ParseUser.getCurrentUser()));

    }
    else {
    }

    toolbar = (Toolbar) findViewById(R.id.app_bar);
    setSupportActionBar(toolbar);

    mPager = (ViewPager) findViewById(R.id.pager);
    mPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
    mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
    mTabs.setDistributeEvenly(true);
    mTabs.setViewPager(mPager);



    try {
        PackageInfo info = getPackageManager().getPackageInfo(
                "com.myflokk.testflokkd",
                PackageManager.GET_SIGNATURES);
        for (Signature signature : info.signatures) {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
        }
    } catch (PackageManager.NameNotFoundException e) {

    } catch (NoSuchAlgorithmException e) {

    }


}

//included onResume as a part of facebook integration
@Override
protected void onResume() {
    super.onResume();

    // Logs 'install' and 'app activate' App Events.
    AppEventsLogger.activateApp(this);
}

//included onPause as a part of facebook integration
@Override
protected void onPause() {
    super.onPause();

    // Logs 'app deactivate' App Event.
    AppEventsLogger.deactivateApp(this);
}



private void navigateToLogin() {
    Intent intent = new Intent(MainActivity.this, LoginActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(intent);
}


@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_main, 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

    switch (id) {

        case R.id.addEvent:
            startActivity(new Intent(this, AddEventActivity.class));
            break;

        case R.id.editProfile:
            startActivity(new Intent(this, UserProfileEditActivity.class));
            break;

        case R.id.action_logout:
            ParseUser.logOut();
            navigateToLogin();
            break;


    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onStart() {
    super.onStart();

    ParseUser currentUser = ParseUser.getCurrentUser();
    if (currentUser == null) {
        navigateToLogin();
        Log.d("Login Check 2", String.valueOf(ParseUser.getCurrentUser()));

    }
    else {
    }

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client.connect();
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://com.myflokk.testflokkd/http/host/path")
    );
    AppIndex.AppIndexApi.start(client, viewAction);
}

@Override
public void onStop() {
    super.onStop();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://com.myflokk.testflokkd/http/host/path")
    );
    AppIndex.AppIndexApi.end(client, viewAction);
    client.disconnect();
}


class MyPagerAdapter extends FragmentPagerAdapter {
    String[] tabs;

    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
        tabs = getResources().getStringArray(R.array.tabs);
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                return new UserEventListFragment();
            case 1:
                return new UserSearchFragment();
            case 2:
                return new UserProfileActivityFragment();
        }
        return null;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabs[position];
    }

    @Override
    public int getCount() {
        return 3;
    }
}
导致错误的事件适配器

protected Context mContext;
protected List<ParseObject> mEvents;
private SimpleDateFormat mFormat = new SimpleDateFormat("E, MMM d", Locale.US);
protected Date mDate;
protected List<Object> mLikeList = new ArrayList<>();
protected int mLikes = 0;
protected String Flokking = "I am flokking to this event!";

public EventAdapter(Context context, List<ParseObject> events) {
    super(context, R.layout.row_event_list, events);
    mContext = context;
    mEvents = events;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;

    if (convertView == null) {

        convertView = LayoutInflater.from(mContext).inflate(R.layout.row_event_list, null);
        holder = new ViewHolder();
        holder.eventName = (TextView) convertView.findViewById(R.id.eventRow_TextEventName);
        holder.eventLocation = (TextView) convertView.findViewById(R.id.eventRow_TextEventLocation);
        holder.eventImage = (ImageView) convertView.findViewById(R.id.eventRow_EventImage);
        holder.eventDate = (TextView) convertView.findViewById(R.id.eventRow_Date);
        holder.eventNotLiked = (ImageView) convertView.findViewById(R.id.eventRow_ImageNotLiked);
        holder.eventLiked = (ImageView) convertView.findViewById(R.id.eventRow_ImageLiked);
        holder.eventFlokkingCount = (TextView) convertView.findViewById(R.id.eventRow_FlokkingCount);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }


    ParseObject event = mEvents.get(position);
    ParseObject details = mEvents.get(position);
    final String currentEvent = details.getObjectId();

    //Log.d("EventAdapter", "This is the position --> " + position);

    holder.eventName.setText(event.getString(ParseConstants.KEY_EVENTNAME));
    holder.eventLocation.setText(event.getString(ParseConstants.KEY_EVENTVENUE));
    holder.eventFlokkingCount.setText(event.getNumber(ParseConstants.EVENT_LIKECOUNT).toString());

    //get the date and assign to mDate and then change the way the date is displayed
    mDate = event.getDate(ParseConstants.KEY_EVENTDATE);
    holder.eventDate.setText(mFormat.format(mDate));


    mLikeList = event.getList(ParseConstants.EVENT_LIKES);
    Log.d("Login Event Check", String.valueOf(ParseUser.getCurrentUser()));

    if (mLikeList == null || mLikeList.isEmpty()) {
        //this is false and the user has not liked the event
        holder.eventLiked.setVisibility(View.INVISIBLE);
        holder.eventNotLiked.setVisibility(View.VISIBLE);
    }

    else {
        //if there are users in the list check for the current user

        if (mLikeList.contains(ParseUser.getCurrentUser().getObjectId())) {
            // true
            holder.eventLiked.setVisibility(View.VISIBLE);
            holder.eventNotLiked.setVisibility(View.INVISIBLE);
        }
        else {
            holder.eventLiked.setVisibility(View.INVISIBLE);
            holder.eventNotLiked.setVisibility(View.VISIBLE);
        }
    }

我不确定你是否意识到,但parse正在逐步减少他们的服务。这可以解释错误,但不能确定。查看他们的网站,他们还提供了一些过渡文档。@YoungCoconutCode感谢您的回复,但我知道这一点,不,这与我的错误无关。谢谢
02-01 19:05:28.800 E/AndroidRuntime: FATAL EXCEPTION: main
                                     Process: com.myflokk.testflokkd, PID: 1933
                                     java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.parse.ParseUser.getObjectId()' on a null object reference
                                         at com.myflokk.testflokkd.Adapters.EventAdapter.getView(EventAdapter.java:98)