Monday, January 21, 2013

Upgrading from 2.0 to 3.0

The new 3.0 SDK makes it easier to manage login, publish to Open Graph, and measure the traffic you're getting from Facebook. The new SDK also provides pre-built native fragments for common tasks like displaying a logged-in user's photo, picking friends, or picking nearby places.
You can read a list of what's new to see some of the changes. For a quick view of what's changed, see the reference table that maps old classes and methods for common tasks to their counterparts in the new SDK.
This guide will take you through the differences between the SDK 2.0 and the SDK 3.0 to help you update your app, including:

How different tasks are handled in the 2.0 and 3.0 SDKs

Task 2.0 way 3.0 way
Login Facebook.authorize Session, instantiated directly or using LoginButton, UserStatusFragment, or UiLifecycleHelper
Check if a user is logged in Facebook.isSessionValid Session.isOpened, Session.isClosed; monitor changes using Session.StatusCallback and UiLifecycleHelper
Refresh an access token Facebook.extendAccessToken Session refreshes this automatically
Make an API call Facebook.request Request, RequestBatch, RequestAsyncTask, Response
Use the feed dialog FBDialog widget.WebDialog.FeedDialogBuilder
Use the requests dialog FBDialog widget.WebDialog.RequestsDialogBuilder
Handle errors FacebookError, DialogError FacebookException, FacebookAuthorizationException, FacebookDialogException, FacebookGraphObjectException, FacebookRequestError or FacebookServiceException

Updating Login in your app

From Facebook to Session, Request, and UiLifecycleHelper

One of the most important differences between the new Facebook SDK 3.0 for Android and previous versions of the SDK is the increased separation of concerns. In earlier versions of the SDK, Login, session state management, and API calls were all handled through a single base class, Facebook.
The Facebook class is deprecated as of the release of the new SDK 3.0. The majority of the functions it provided are now separated between the Session, Request, and UiLifecycleHelper classes. This section will take you through the changes relating to Login. Read the Login tutorial for step-by-step instructions on adding Login to your app the 3.0 way.
To update your app, first add a reference to your App ID into the AndroidManifest.xml file. Since you are no longer using your App ID to instantiate a Facebook object, you will need to include the following line to allow the SDK to identify your application on Facebook:
 <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/>
Next, add a string resource to your strings.xml file with your App ID.
 <string name="app_id">12345678910</string>
Login is now handled through the Session class. When you want to log a user in with Facebook, you'll need to instantiate a new Session object, like this:
 Session session = new Session(getApplicationContext());
You have the option of passing in your App ID as a parameter, but if you do not, Session will grab the App ID from your manifest file.
Session objects have an associated private AccessToken object that handles the user's access token. When the Session is created, it attempts to initialize itself from a TokenCache, an object that is automatically created to store the user's most recent access token.
If the cache exists, and contains a valid access token, the Session will be created using that token. if none exists, or if the token has expired, the Session object will create a TokenCache with an empty AccessToken object that has no associated permissions. You do not need to do anything for this to happen.
Instances of Session have a state machine corresponding to their lifecycle that can take the following states: CREATED, CREATED_TOKEN_LOADED, OPENING, OPENED, OPENED_TOKEN_UPDATED, CLOSED, and CLOSED_LOGIN_FAILED. They provide state change notification via a callback interface, StatusCallback.
Once you have created a Session, it is either in the CREATED state (meaning there was no valid access token at create time) or the CREATED_TOKEN_LOADED state (it was created from a valid token TokenCache). To make any API call, your session must be taken from CREATED to OPEN by calling one of the Session.open() methods. Opening a session is the same as logging a user in to Facebook.
If your session is in the CREATED state, calling one of the open() functions will prompt your user to log in to Facebook; you will have to handle cases where login fails. If the session is in the CREATED_TOKEN_LOADED state, your user will not have to go through the login flow again.
Once you have logged a user in successfully and received an access token, Session automatically refreshes and extends the lifetime of this token if needed. If you need a new token (for example, if your user logged out of Facebook on their phone), Session will automatically take your user through the authorization flow again. You no longer have to write code to extend the access token yourself.
Note: In the new SDK, you may ask only for read permissions when you first open a session. You should not prompt your user for publish permissions until the time at which they are actually publishing an action to Facebook. This increases user trust, and also the likelihood that your user will choose to publish stories from your app. To request further permissions, use Session.openForRead or Session.openForPublish.

Manage Sessions with UiLifecycleHelper

The new SDK also provides a UiLifecycleHelper class that helps create, automatically open (if applicable), save, and restore the active Session in a way that is similar to Android UI lifecycle methods. You can add the UiLifecycleHelper and set up a corresponding Session.StatusCallback listener in any activity or fragment where you wish to track and respond to session state changes.
For each of the Android lifecycle methods, there is a corresponding UiLifecycleHelper method that handles everything that should happen to the Session at that time. For example, calling the UiLifecycleHelper's onCreate() method creates a Facebook session and opens it automatically if a cached token is available.
To use this class, first instantiate a UiLifecycleHelper object in the onCreate() method of the relevant Activity or Fragment using the current Activity and your StatusCallback:
uiHelper = new UiLifecycleHelper(getActivity(), callback);
You can then override lifecycle methods to add their corresponding UiLifecycleHelper methods like this:
@Override
public void onResume() {
    super.onResume();
    uiHelper.onResume(); 
}
For more details on UiLifecycleHelper and managing login, read the Login tutorial.

Importing 2.0 Tokens

You can import tokens you stored with the 2.0 SDK. This allows for a seamless login experience for users upgrading to your 3.0 SDK-based app. This means that if the user was previously logged in, they won't have to go through the log in flow after they upgrade your app. To enable this, all you have to do is add code to pass the token from one SDK session management system to the other.
The Session class has an open() method that can take in an AccessToken object to open a session. The AccessToken object can be created from a previously stored access token.
In this quick example, assume that in your 2.0 SDK integration you stored the access token in SharedPreferences when the user was authenticated:
// Save session data
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token", facebook.getAccessToken());
editor.putLong("access_expires", facebook.getAccessExpires());
editor.commit();
The access token was stored under the ''access_token'' key along with the access token expiration info. You can use the following logic to import the token in your 3.0 SDK integration:
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
    String access_token = mPrefs.getString("access_token", null);

    Session session = Session.getActiveSession();
    if (session == null) {      
        // Check if there is an existing token to be migrated 
        if(access_token != null) {                              
            // Clear the token info
            SharedPreferences.Editor editor = mPrefs.edit();
            editor.putString("access_token", null);
            editor.commit();    
            // Create an AccessToken object for importing
            // just pass in the access token and take the
            // defaults on other values
            AccessToken accessToken = AccessToken.createFromExistingAccessToken(
                                        access_token,
                                        null, null, null, null);
            // statusCallback: Session.StatusCallback implementation
            session.open(accessToken, statusCallback);
            Session.setActiveSession(session);
        }
    }
    ...
}
The code checks SharedPreferences for the access token you previously stored. If a token is found, a session is opened after an AccessToken object is created using the createFromExistingAccessToken() static method. In this code, the AccessToken is created with a null value for the access token expiration date. This results in an initial infinite expiration time that is later set to the correct value when the token is refreshed.
The code also clears the access token in SharedPreferences to make sure this is a one-time import event. The statusCallback variable in the code corresponds to a pre-defined Session.StatusCallback listener where you'll respond to session state changes.
If using the UiLifecycleHelper class to help manage your session, you should add the token import logic before instantiating a UiLifecycleHelper instance.
Once you've imported the 2.0 SDK token, the user's session will now be managed by the 3.0 SDK system.

Login view and fragment classes to manage login

The pre-built LoginButton and UserSettingsFragment classes in the SDK provide a pre-built UI and can also handle Session creation for you.
The LoginButton is a view class that can easily be added to your application. Include it in your layout file like this:
 <com.facebook.LoginButton
        android:id="@+id/authButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="30dp"
/>
If you require only the basic permissions from your user, this is all the code you'll have to add before making API calls. If you want more permissions, declare a private LoginButton variable, and request permissions like this:
LoginButton authButton = (LoginButton) view.findViewById(R.id.authButton);
authButton.setReadPermissions(Arrays.asList("user_likes", "user_status"));
The button automatically manages the correct display text ("Login"/"Log out"), and creates the necessary Session.StatusCallback interfaces to notify you of changes to your user's login state.
In addition, we recommend that you add LoginActivity to your Android XML file to prevent window leaks during authorization if the Activity containing the dialog is destroyed, for example if the user rotates the device.

Making API Calls to Facebook

Using the Request, RequestBatch, and RequestAsyncTask classes

The latest version of the SDK also makes it substantially easier to make asynchronous API calls and to batch requests for fewer calls to the service. Note that AsyncFacebookRunner has been deprecated.
API calls are now made through the new Request class. There are many ways to construct Request objects, depending on what you need them to do. Most Requests are instantiated using the current Session (to identify the user and the permissions they've granted your app) and the graph path at which data will be retrieved, created, or deleted (e.g. graph.facebook.com/me).
You can also specify a Bundle of additional parameters to pass along with the Request. For example, if you are posting a checkin, the graph path should be /me/checkins, and the Bundle of parameters should include the place ID and coordinates of the checkin. This is similar to how requests were sent in the old SDK.
You should define a Request.Callback to handle the response. You can see an example of how to set up requests in the publish to feed tutorial.
AsyncFacebookRunner has been deprecated; to execute Requestst asynchronously, use RequestAsyncTask:
    RequestAsyncTask task = new RequestAsyncTask(request); 
    task.execute();
If you have many API calls to make, you can batch up to 50 at once using RequestBatch.
We also provide Request methods for common tasks:
  • newMeRequest(Session session, Request.GraphUserCallback callback): retrieve the user's profile
  • newMyFriendsRequest(Session session, Request.GraphUserListCallback callback): retrieve the user's friend list
  • newUploadPhotoRequest(Session session, Bitmap image, Request.Callback callback): upload a photo to the user's default photo album.
  • newPlacesSearchRequest(Session session, Location location, int radiusInMeters, int resultsLimit, String searchText, Request.GraphPlaceListCallback callback): perform a search for places near a specified location via the Graph API
  • newStatusUpdateRequest(Session session, String message, Request.Callback callback): post a status to a user's feed
Alongside the Request objects, the new SDK also includes a GraphObject interface that provides strongly-typed getters and setters for data fetched from the Graph API. For example, the GraphUser interface allows you to getBirthday(), and the GraphPlace interface contains the method getLocation().

New native views for choosing friends or places

Use Friend Picker and Place Picker in your app

We now also provide pre-built views for choosing friends or locations on Facebook within your app. The UI is exposed as a Fragment to allow to it to be included in an Activity along with other Fragments if you wish. These PickerFragments support callbacks that will be called in the event of an error, when the underlying data has been changed, or when the set of selected graph objects changes.
There are detailed tutorials on how to implement the Friend Picker and the [Place Picker[(https://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/show-nearby-places/).

Mobile App Install Ads

Track successful app installs by publishing to your Insights dashboard

You can now promote your mobile app directly in people's news feeds using Facebook's mobile app install ads. You can advertise this way regardless of whether your app uses Facebook.
The SDK 3.0 features a method in the Settings class called publishInstallAsync(context, YOUR_APP_ID) that asynchronously pings an install event to Facebook when it's invoked. Include it in the onCreate() method of your app's launcher activity, like this:
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   Settings.publishInstallAsync(getApplicationContext(), appId);
   ...
 }
The Settings class internally handles tracking repeat calls to prevent multiple installs from the same device being published.
Once you have this line of code in your app, you can go to the App Dashboard to configure text and images for your ad.
A step-by-step walkthrough for setting up mobile app install ads is available here.
Source:Facebook.

No comments:

Post a Comment