回 Android手機程式設計人才培訓班 課程時間表

Facebook API介紹

簡介

Facebook針對各種不同平台推出了:Web、Android和iOS的軟體開發套件(Software Development Kit簡稱SDK),為了安全性,在使用上必須針對應用程式設定並申請App ID才能使用,且因為Facebook版本演化的關係,開發方式略有不同,此處針對目前最新版本3.23.1(2015-3-12更新)做介紹

Facebook SDK for Android下載:https://developers.facebook.com/docs/android/downloads


FaceBook SDK開發Android應用程式步驟

  1. 加入Facebook開發者,申請網址:https://developers.facebook.com。從上面選項My Apps選擇Register as a Developer。
    申請加入Facebook開發必須通過電話認證。

  2. 加入後,上面選項My Apps選擇後會出現Add a New App選項,點選後再選擇Android。

  3. 輸入你要建立的App名稱,並選取類別後點選Create App ID。
    注意:如果你的App包含某些單字,將無法建立,例如:Facebook、Face、FB、Poke、Book、Wall和Instagram等等。
  4. 下載Facebook SDK。

  5. 安裝Facebook App(如果是使用模擬器的話可以在這裡下載apk版本,並透過adb工具來安裝)。

    Mac安裝方式:
    $ ./adb install ~/Downloads/Facebook-11.apk
    Windows安裝方式:
    D:\Android\sdk\platform-tools\adb install %HOMEPATH%\Downloads\Facebook-11.apk

  6. 建立你的Android專案,Blank Activity即可(使用的Android SDK版本至少必須是API Level 9, Android 2.3以上)。

  7. 修改專案的build.gradle (Module:app)檔案。加入repositories和compile兩行,完整檔案參考如下:
    apply plugin: 'com.android.application'
    
    android {
        signingConfigs {
        }
        compileSdkVersion 21
        buildToolsVersion "21.1.2"
        defaultConfig {
            applicationId "com.aaronlife.hellosocial"
            minSdkVersion 14
            targetSdkVersion 21
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    repositories { mavenCentral() }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:21.0.3'
        compile 'com.facebook.android:facebook-android-sdk:3.21.1'
    }
    
  8. 匯入Facebook SDK到專案內。

    先將下載的facebook-android-sdk-3.23.1.zip解壓縮後,在Android Studio上面選單選擇File->Import Module來匯入。

  9. 設定「套件」名稱和「應用程式預設的Activity包含套件名的完整名稱」(通常為MainActivity)。

  10. 設定Key Hash(分為開發和發佈兩種版本):

    開發版本的Key Hash為必須使用debug.keystore檔案,一般存放在使用者家目錄下的.android目錄內:

    Mac或Linux:
    $ keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
    Windows:
    keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64

    發佈版本的Key Hash必須先建立應用程式的keystore,然後keytool工具來產生:

    $ keytool -exportcert -alias {你的keystore Alias名稱} -keystore {你的keystore路徑及檔名} | openssl sha1 -binary | openssl base64
    備註1:可直接透過Android Studio的Terminal視窗進行。
    備註2:Windows下因為缺少OpenSSL程式,所以必須先到http://gnuwin32.sourceforge.net/packages/openssl.htm下載後,並設定目錄\openssl-0.9.8h-1-bin\bin到環境變數Path中。
  11. 修正專案內的設定問題:
    • 因為facebook專案內缺少Android SDK版本的相關定義,所以必須在gradle.properties (Project Properties)檔案內最下方加入下面四行版本相關定義(可根據專案版本自行調整):
      ANDROID_BUILD_SDK_VERSION=21
      ANDROID_BUILD_TOOLS_VERSION=21.1.2
      ANDROID_BUILD_MIN_SDK_VERSION=14
      ANDROID_BUILD_TARGET_SDK_VERSION=21
      
    • 更改build.gradle (Project: HelloSocial)檔案內的Gradle plugin版本;因為Gradle plugin 1.1.0版的問題,會出現編譯錯誤,因此必須改用1.1.1以後的版本,這裏改為使用最新的1.1.3版:
      uildscript {
          repositories {
              jcenter()
          }
          dependencies {
              classpath 'com.android.tools.build:gradle:1.1.3'
      
              // NOTE: Do not place your application dependencies here; they belong
              // in the individual module build.gradle files
          }
      }
      
      修改完後請記得執行:Sync Project with Gradle Files。
      Sync後,Android Studio可能會詢問你是否要重新載入專案,回答「Yes」即可。
  12. 讓Facebook可以追蹤你的應用程式安裝或執行的相關動作。 在Activity內覆載onResume()onPause()方法,加入下面程式碼:
    @Override
    protected void onResume() 
    {
        super.onResume();
    
        // 紀錄應用程式被「安裝」和「執行」的事件。
        AppEventsLogger.activateApp(this);
    }
    
    @Override
    protected void onPause() 
    {
        super.onPause();
    
        // 紀錄應用程式「結束」的事件。
        AppEventsLogger.deactivateApp(this);
    }
    
  13. 在res/values/strings.xml中加入AppID:
    <string name="app_id">{這裏填入你的APP ID字串}</string>
  14. 在AndroidManifest.xml中加入必要的權限和資料: 在Manifest標籤中加入android.permission.INTERNET權限:
    <uses-permission android:name="android.permission.INTERNET"/>
    application標籤中加入Facebook需要用到的資料:
    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/>
    <activity android:name="com.facebook.LoginActivity"
        android:theme="@android:style/Theme.Translucent.NoTitleBar"
        android:label="@string/app_name" />
    
    <provider android:authorities="com.facebook.app.NativeAppCallContentProvider0000000000000000000"
        android:name="com.facebook.NativeAppCallContentProvider"
        android:exported="true"/>
    
    備註:provider標籤內的:0000000000000000000請改為你的App ID。
  15. 版面設計res/layout/activity_main.xml:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        tools:context=".MainActivity">
    
        <com.facebook.widget.ProfilePictureView
            android:id="@+id/profilePicture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp" />
    
        <com.facebook.widget.LoginButton
            android:id="@+id/authButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp" />
    
        <TextView
            android:text="臉書使用者資訊"
            android:textSize="24sp"
            android:layout_marginTop="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
        <TextView android:id="@+id/loginInfo"
            android:lines="10"
            android:textSize="20sp"
            android:layout_margin="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:layout_margin="10dp"
                android:textSize="20sp"
                android:textColor="#ffffff"
                android:background="#6d84b4"
                android:text="Post文章"
                android:onClick="postStatus"/>
    
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:layout_margin="10dp"
                android:textSize="20sp"
                android:textColor="#ffffff"
                android:background="#6d84b4"
                android:text="Post照片"
                android:onClick="postPhoto"/>
        </LinearLayout>
    </LinearLayout>
    
  16. 撰寫程式碼,並加入需要的功能,src/MainActivity.java:
    package com.aaronlife.hellosocial;
    
    import android.content.Intent;
    import android.graphics.drawable.BitmapDrawable;
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.view.View;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.facebook.AppEventsLogger;
    import com.facebook.Session;
    import com.facebook.SessionState;
    import com.facebook.UiLifecycleHelper;
    import com.facebook.model.GraphUser;
    import com.facebook.widget.FacebookDialog;
    import com.facebook.widget.LoginButton;
    import com.facebook.widget.ProfilePictureView;
    
    import java.util.Arrays;
    
    
    public class MainActivity extends ActionBarActivity
    {
        private LoginButton loginButton;          // Facebook SDK的登入按鈕
        private TextView loginInfo;               // 顯示使用者資訊用
        private GraphUser user;                   // Facebook SDK登入後取得的使用者資訊物件
        private UiLifecycleHelper uiHelper;       // Facebook SDK介面幫助類別
        private ProfilePictureView userimage;     // Facebook SDK的照片元件
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 關聯UI元件
            loginInfo = (TextView)findViewById(R.id.loginInfo);
            userimage = (ProfilePictureView) this.findViewById(R.id.profilePicture);
            loginButton = (LoginButton) findViewById(R.id.authButton);
    
            // 建立UiLifecycleHelper物件,並傳入Session.StatusCallback處理臉書登入狀態事件
            uiHelper = new UiLifecycleHelper(this, callback);
    
            // 設定需要取得的Facebook權限
            loginButton.setReadPermissions(Arrays.asList("email", "public_profile", "user_friends"));
    
            // 設定收到來自Facebook的使用者資訊傾聽器
            loginButton.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback()
            {
                @Override
                public void onUserInfoFetched(GraphUser user)
                {
                    MainActivity.this.user = user;
                    updateUI();
                }
            });
    
            // 設定Session.Callback物件給LoginButton
            loginButton.setSessionStatusCallback(callback);
        }
    
        @Override
        protected void onResume()
        {
            super.onResume();
    
            // 紀錄應用程式被「安裝」和「執行」的事件。
            AppEventsLogger.activateApp(this);
        }
    
        @Override
        protected void onPause()
        {
            super.onPause();
    
            // 紀錄應用程式「結束」的事件。
            AppEventsLogger.deactivateApp(this);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
            super.onActivityResult(requestCode, resultCode, data);
    
            // 接收Facebook Activity的回傳值,並交給UiLifecycleHelper物件處理
            uiHelper.onActivityResult(requestCode, resultCode, data, dialogCallback);
        }
    
        // Facebook SDK狀態Callbak物件
        Session.StatusCallback callback = new Session.StatusCallback()
        {
            @Override
            public void call(Session session, SessionState state, Exception exception)
            {
                if (state.isOpened())
                {
                    Toast.makeText(MainActivity.this, "已登入。", Toast.LENGTH_SHORT).show();
                }
                else
                {
                    Toast.makeText(MainActivity.this, "已登出。", Toast.LENGTH_SHORT).show();
                }
    
                // 更新介面
                updateUI();
            }
        };
    
        // 使用者在Facebook上的執行的動作結果,例如發表文章、照片的成功或失敗
        private FacebookDialog.Callback dialogCallback = new FacebookDialog.Callback()
        {
            @Override
            public void onError(FacebookDialog.PendingCall pendingCall, Exception error, Bundle data)
            {
                Toast.makeText(MainActivity.this, "Error: " + error.toString(), Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data)
            {
                // 檢查使用者動作結果
                String completionGesture = FacebookDialog.getNativeDialogCompletionGesture(data);
    
                if(completionGesture.equals("post"))
                    Toast.makeText(MainActivity.this, "張貼完成。", Toast.LENGTH_SHORT).show();
                else
                    Toast.makeText(MainActivity.this, "張貼取消。", Toast.LENGTH_SHORT).show();
            }
        };
    
        // 更新介面
        private void updateUI()
        {
            Session session = Session.getActiveSession();
    
            // 取得使者登入狀態
            boolean enableButtons = (session != null && session.isOpened());
    
            if(enableButtons && user != null)
            {
                // 使用者資訊
                loginInfo.setText("ID: " + user.getId() + "\n" +
                "Name: " + user.getName() + "\n" +
                "First Name: " + user.getFirstName() + "\n" +
                "Last Name:" + user.getLastName() + "\n" +
                "email: " + user.getProperty("email"));
    
                // 取得使用者大頭照
                userimage.setProfileId(user.getId());
            }
            else if (session != null && session.isClosed())
            {
                user = null;
                loginInfo.setText("尚未登入");
                userimage.setProfileId(null);
            }
            else
            {
                loginInfo.setText("登入錯誤");
            }
        }
    
        public void postStatus(View view)
        {
            // 判斷使用者安裝的Facebook App是否可以提供該功能
            if(FacebookDialog.canPresentShareDialog(this, FacebookDialog.ShareDialogFeature.SHARE_DIALOG))
            {
                // 使用FacebookDialog.ShareDialog來張貼文章
                FacebookDialog shareDialog = new FacebookDialog.ShareDialogBuilder(this)
                        .setLink("http://www.aaronlife.com") // 要張貼的連結
                        .setPicture("http://www.aaronlife.com/travel/images/travel_2014-09-16_13.jpg") // 照片連結
                        .build();
    
                uiHelper.trackPendingDialogCall(shareDialog.present()); // 切換到張貼狀態的Facebook Activity
            }
            else
            {
                Toast.makeText(this, "不支援Sharedialog", Toast.LENGTH_SHORT).show();
            }
        }
    
        public void postPhoto(View view)
        {
            // 判斷使用者安裝的Facebook App是否可以提供該功能
            if(FacebookDialog.canPresentShareDialog(this, FacebookDialog.ShareDialogFeature.PHOTOS))
            {
                // 使用FacebookDialog.PhotoShareDialog來張貼文章
                FacebookDialog sharePhotoDialog = new FacebookDialog.PhotoShareDialogBuilder(this)
                    .addPhotos(Arrays.asList(((BitmapDrawable) getResources().getDrawable(R.drawable.icon)).getBitmap())) // 要張貼的照片
                    .build();
    
                uiHelper.trackPendingDialogCall(sharePhotoDialog.present()); // 切換到張貼照片的Facebook Activity
            }
            else
            {
                Toast.makeText(this, "不支援PhotoShareDialog", Toast.LENGTH_SHORT).show();
            }
        }
    }
    
  17. 加入應用程式用到的資源,如:drawable/icon.png等等。

  18. 最後,你必須設定聯絡信箱email:
    設定完記得點選「Save Changes」來儲存。
  19. 然後,公開你的App:
  20. 完成。