2013年7月18日 星期四

[Android][Facebook][中文化] Facebook SDK for Android Tutorial - Personalize

2 - Personalize


這個教學列出使用 Facebook SDK for android 如何個人化你的app 經驗的大綱。個人化則藉由顯示使用者的 profile 裡的照片與名子來達成。
  • 使用 Request,   來建構一個使用Facebook API calls 的單一要求 。 需要被授權的使用者的一個request, 它必須在一個 open Session 被傳遞。Request 也可以是匿名的, 這是說它們並不一定需要一個使用者來授權。 在這個例子裡, 沒有  Session 需要被定義出來。當一個Request 被完成時, 假如有需要的話 , Facebook SDK 將在background 裡延展 access token 。 
  • Response 封裝了來自Facebook API call 的 response
  • ProfilePictureView 是一個顯示profile 照片的客製化 view 
  • GraphUse 是一個 提供一個強烈樣式表現的介面


你將會使用這些class 跟 interface 來獲取使用者的基本資訊以用來個人化你的 app。 你將使用一個 屬於 Request class 叫做 newMeRequest() 的靜態的方法呼叫程序。 這個方法會回傳使用者的資料。 當設定好 request , 你將定義一個 callback 來處理回復。這個回復是一個 GraphUser 種類的物件。你也將處理被傳回的使用者物件, 然後使用ProfilePictureView 顯示出使用者 profile 的照片,使用 TextView 顯示使用者的名子。

這個教學帶領你走過
  • 步驟 1 : 設定使用者介面
  • 步驟 2 : 展示使用者資訊
  • 下一步
  • 相關範例
注意: 在你開始這個個人化的 app 前, 確認你已經設定好授權了。

步驟 1 : 設定使用者介面




在這個步驟, 你將設定使用者介面來展示使用者 profile 的照片跟名子。

在前面的教學理, 你建立了一個基本授權狀態與使用TextView展示歡迎訊息的UI 。現在你將去除這個TextView 取代而之的是然後使用者 profile 的照片和名子。



打開authenicated view 的layout: res/layout/selection.xml。 去掉 TextView 元件, 然後取而代之的是一個LinearLayout , 它又包含著一個用來展示使用者profile 照片的ProfilePictureView與一個用來展示她們名子 的 Textview。


<LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >
    <com.facebook.widget.ProfilePictureView
            android:id="@+id/selection_profile_pic"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_gravity="center"
            android:gravity="center_horizontal"
            facebook:preset_size="small" />
    <TextView
            android:id="@+id/selection_user_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_gravity="center"
            android:textColor="#333"
            android:textSize="18sp" />
</LinearLayout>

你應該會得到一個錯誤訊息關於客製 custom view: com.facebook.widget.ProfilePictureView.  加上 facebook namespace 在目前的 package上

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:facebook="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
....

乎視那些關於 一個 LinearLayout 伴隨著另一個LinearLayout 的警示訊息。 稍後你加入更多 components 後, 這個訊息就會消失了。

步驟 2 : 展示使用者資訊

在這個步驟 ,你將加入展是使用者照片與名子資料的邏輯步驟。

開啟 SelectionFragment class 並做一些修改。首先定義用來設定使用者照片與名稱資料的 private variables 。
private ProfilePictureView profilePictureView;
private TextView userNameView;

接下來修改 onCreateView() 方法來只定變數給相關的 layout element :

View view = inflater.inflate(R.layout.selection, container, false);

// Find the user's profile picture custom view
profilePictureView = (ProfilePictureView) view.findViewById(R.id.selection_profile_pic);
profilePictureView.setCropped(true);

// Find the user's name view
userNameView = (TextView) view.findViewById(R.id.selection_user_name);

當 session 打開時, 你將執行一個 API call 來獲取 使用者資料以及完整這個畫面。 之前在authenticate 交學使用過的 UiLifecycleHelper class ,  也可以用在 SelectionFragment class 來偵測 session 狀態的改變然後觸發使用者資料的 API call
首先, 建立一個 private 方法用來要求使用者資料:

private void makeMeRequest(final Session session) {
    // Make an API call to get user data and define a 
    // new callback to handle the response.
    Request request = Request.newMeRequest(session, 
            new Request.GraphUserCallback() {
        @Override
        public void onCompleted(GraphUser user, Response response) {
            // If the response is successful
            if (session == Session.getActiveSession()) {
                if (user != null) {
                    // Set the id for the ProfilePictureView
                    // view that in turn displays the profile picture.
                    profilePictureView.setProfileId(user.getId());
                    // Set the Textview's text to the user's name.
                    userNameView.setText(user.getName());
                }
            }
            if (response.getError() != null) {
                // Handle errors, will do so later.
            }
        }
    });
    request.executeAsync();
} 

你也許需要整理一下 import 在你加入這段 code 以後, 因為會有錯誤。 假如你是經由 Eclipse 來 import 的話, 選擇 com.facebook.Session 當你看到這選項時。 同樣的選擇 com.facebook.Request 當你看到這選項。

將下來定義一個private 方法來回應 session 的改變然後呼叫 makeMeRequest() 方法 假如 session 打開了:

private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
    if (session != null && session.isOpened()) {
        // Get the user's data.
        makeMeRequest(session);
    }
}

現在你已經設定好對 session state 改變的回應方式, 你可以設定 UiLifecycleHelper instance以及一個關連的 會呼叫 onSessionStateChange() 方法的 listener

定義 private 變數給 UiLifecycleHelper 物件 還有 Session.StatusCallback listener 的 implementation。 這個 listener 覆寫 call() 方法來開啟 之前定義的 onSessionStateChange() 方法

private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
    @Override
    public void call(final Session session, final SessionState state, final Exception exception) {
        onSessionStateChange(session, state, exception);
    }
};

接下來覆寫 onCreate()方法來初始化 UiLifecycleHelper 物件然後呼叫它的 onCreate()方法 :


接下來, 定義一個 private 常數, 稍後你將會在每次要求一個新的 permissions request 食用道。你將用他來決定在 onActivityResult()時要不要更新一個 session 得資訊:

private static final int REAUTH_ACTIVITY_CODE = 100;

現在覆寫 onActivityResult() 方法然後呼叫對應的 UiLifecycleHelper 方法假如 REAUTH_ACTIVITY_CODE request code 被送進去時

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REAUTH_ACTIVITY_CODE) {
        uiHelper.onActivityResult(requestCode, resultCode, data);
    }
}

接下來確認其他的 fragment 生命週期的方法會呼叫相關 UiLifecycleHelper  class方法:

@Override
public void onResume() {
    super.onResume();
    uiHelper.onResume();
}

@Override
public void onSaveInstanceState(Bundle bundle) {
    super.onSaveInstanceState(bundle);
    uiHelper.onSaveInstanceState(bundle);
}

@Override
public void onPause() {
    super.onPause();
    uiHelper.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    uiHelper.onDestroy();
}

最後, 一但 fragment 設定好了然後一個使用者的 session 打開了, 獲取使用者資料。 修改 onCreateView() 方法來做這件事 :

....
// Check for an open session
    Session session = Session.getActiveSession();
    if (session != null && session.isOpened()) {
        // Get the user's data
        makeMeRequest(session);
    }

確保沒有任何錯誤訊息下, Build 跟 run project 。 登入。 你應該會看到你的檔案照片和你的名子







2 則留言:

  1. 十分感謝,真開心有這麼一篇詳細的解說,對於英文十分頭痛的我給了個良藥,謝謝你~非常有幫助^^

    回覆刪除
  2. 而在複寫oncreat()z方法那邊的code:

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    uiHelper = new UiLifecycleHelper(getActivity(), callback);
    uiHelper.onCreate(savedInstanceState);
    }

    回覆刪除