Search code examples
androidfacebookfacebook-graph-apimulti-friend-selector

Android - Facebook SDK - FriendPicker setSelected not working


I just implemented the friend picker using Facebook's provided SDK fro Android. Everything seems to be working fine except for if a user wants to go back into the picker and edit their friend selection. I'm able to get the previously selected friends, and call setSelection on the friendPickerFragment (which receives the List object, confirmed via Log.d). However, the friends are NOT being pre-selected!! In my PickerActivity I am calling:

@Override
protected void onResume() {
    super.onResume();
    if (FRIEND_PICKER.equals(getIntent().getData())) {
        Log.d(LOG, "HERE");
        try {
            if (selectedFriends()!=null) {
                Log.d(LOG, "U HAVE FRIENDS: " + selectedFriends().size());
                friendPickerFragment.setSelection(selectedFriends());
            }
            friendPickerFragment.setFriendPickerType(FriendPickerType.TAGGABLE_FRIENDS);
            friendPickerFragment.loadData(false);
        } catch (Exception ex) {
            onError(ex);
        }
    }
}

I've also tried only calling setSelection, thinking that perhaps the call to loadData was wiping out the selections... but still no luck. I've also noticed tht for my PickerActivity (as designed by the Scrumptious fb tutorial) onCreate is called everytime I open the friend picker... likely forcing a reload of the data. Does anyone have experience getting this to work? I'm stumped at the moment. Thanks in advance.


Solution

  • To understand this response you'll need to read my comments under the original question above.

    What I found: When you change Facebook's FriendPickerFragment to type FriendPickerType.TAGGABLE_FRIENDS the data returned is setup not to be cached. This means that every time the friend picker is shown the data is reloaded, which for some reason causes any previously selected friends not to be reselected after the reload completes. I'm still not sure why that is, because it seems like the FriendPickerFragment still has reference to those selected friends via it's preSelectedFriendIds List<String> object (So a better solution may be determining why that is happening). Furthermore, if you change the FriendPickerType.TAGGABLE_FRIENDS to allow caching, when you relaunch the FriendPickerFragment you momentarily see that your previously selected friends are in-fact selected, but then the FriendPickerFragment realizes that it loaded data (even if only some) from the cache, which causes it to refresh it's data! Again, resetting the previously selected friends!

    What I did to workaround: This is perhaps not the best way to go about this, as I'm sure Facebook made the FriendPickerType.TAGGABLE_FRIENDS non-cacheable for a reason. My initial thinking is that it's because if it's loading from the cache it may not always contain the users full list of friends, or perhaps it's just a lot of friends (data) to cache. However, I switched the type to cacheable. Then I added a boolean to the FriendPickerFragment that indicates whether or not this is the first time the data has been loaded. If you follow the Facebook tutorial you'll see that they setup the FriendPickerFragment using a static method named populateParameters(Intent intent, String userId, boolean multiSelect, boolean showTitleBar, boolean initialLoad). Before launching the FriendPicker I check in my launching Activity if the FriendPicker has already been shown or not. If it hasn't I set the initialLoad boolean to true, otherwise if it has already been shown I set the initial boolean to false. This boolean controls the onLoadFinished() method found in Facebook's FriendPickerFragment under the private class ImmediateLoadingStrategy:

        private class ImmediateLoadingStrategy extends LoadingStrategy {
        @Override
        protected void onLoadFinished(GraphObjectPagingLoader<GraphUser> loader, SimpleGraphObjectCursor<GraphUser> data) {
            super.onLoadFinished(loader, data);
            // We could be called in this state if we are clearing data or if we are being re-attached
            // in the middle of a query.
            if (data == null || loader.isLoading()) {
                return;
            }
            if (data.areMoreObjectsAvailable()) {
                // We got results, but more are available.
                followNextLink();
            } else {
                // We finished loading results.
                hideActivityCircle();
    
                // If this was from the cache, schedule a delayed refresh query (unless we got no results
                // at all, in which case refresh immediately.
                if (data.isFromCache() && initialLoad==true) {
                    loader.refreshOriginalRequest(data.getCount() == 0 ? CACHED_RESULT_REFRESH_DELAY : 0);
                }
            }
        }
    }
    

    Note the added check && initialLoad==true - this (a) makes sure that if this is the first time the friendpicker is shown the friends list is updated and (b) if it has already been shown once during this run of the app, it is not refreshed. This ensures that the previously selected friends remain selected.

    If someone has a better solution I'd love to hear it :)