วิธีใส่ปุ่ม Facebook Like ลงในแอพฯแอนดรอยด์โดยใช้ Facebook SDK for Android v4

Posted on 27 Apr 2015 16:52 | 26625 reads | 0 shares
 

ปุ่ม Like ถือเป็นหนึ่งในสิ่งที่แทบทุกเว็บต้องมีไว้เพื่อเพิ่ม Reach ของเว็บ พอมาอยู่ในยุคที่ Traffic จำนวนมากมาจาก Mobile จึงไม่ต้องแปลกใจที่ Facebook จึงจัดปุ่ม Like แบบ Native อย่าง LikeView มาให้เราใช้แปะลงไปในแอพฯเรียบร้อย

likes

อย่างไรก็ตาม การแปะ LikeView ลงแอพฯอาจจะฟังดูง่ายๆ แต่ปรากฎว่าเวลาใช้จริงกลับไม่ง่ายอย่างที่คิด การแปะลงไปด้วยวิธีปกติกลับใช้งานไม่ได้ครบฟังก์ชั่น ยกตัวอย่างเช่นไม่สามารถดูได้ว่ามีคน Like แล้วกี่คน ทำเอาใช้งานจริงแทบไม่ได้ แถมถ้าเอาไปลงบนเครื่องที่ไม่ได้ลงแอพฯ Facebook ไว้ ก็จะใช้งานปุ่มนี้ไม่ได้อีก ซึ่งต่างจากการแปะลงบนเว็บซึ่งตรงไปตรงมาและใช้งานได้ทันที ไม่มีปัญหาจุกจิกกวนใจ

หลังจากที่พยายามนั่งอ่าน Source Code ของ Facebook SDK จึงพบว่าปัญหาเหล่านี้เกิดขึ้นเพราะ LikeView ถูกออกแบบมาให้ทำงานได้อย่างเต็มประสิทธิภาพก็ต่อเมื่อแอพฯนั้นๆเชื่อมต่อกับ Facebook แล้วเท่านั้น ส่งผลให้ถ้าแค่แปะปุ่ม LikeView ลงไปโดยยังไม่เชื่อมต่อแอพฯเข้ากับ Facebook ก็จะทำให้ใช้งานได้ไม่สมบูรณ์

หลังจากทำการทดลองมาหลายวิธี สุดท้ายก็ได้วิธีที่สามารถใช้งานได้อย่างสมบูรณ์ วันนี้เราเลยขอเอาวิธีการแปะ LikeView ลงในแอพฯแอนดรอยด์ของท่านมาเล่าให้ฟังกันแบบ Step by Step ครับ =)

สร้าง Facebook App

การใช้ LikeView ได้เราจำเป็นต้องสร้าง Facebook App เพื่อกำหนดการเชื่อมต่อกับแอพฯของเรา สามารถสร้างได้ด้วยวิธีง่ายๆดังนี้

เข้าเว็บ https://developers.facebook.com/apps แล้วกด Add a New App เพื่อสร้าง App ใหม่

addnewapp

ใส่ชื่อ Facebook App ที่ต้องการแล้วกด Create New Facebook App ID

newapp2

เลือก Category แล้วกด Create App ID

categoryselection

จะเข้าสู่หน้าตั้งค่า Facebook App ให้ Scroll ลงไปล่างสุดพร้อมใส่ชื่อ Package และชื่อ Class Activity หลักของแอพฯแล้วกด Next

classes

จากนั้นเราต้องสร้าง Key Hash สำหรับ Debug Keystore เพื่อให้แอพฯในโหมด Debug เราสามารถใช้งานร่วมกับ Facebook App ที่สร้างขึ้นได้ และต้องใส่ Release Key Hash เพื่อให้แอพฯบน Production สามารถใช้งานได้

keyhashesbefore

วิธีที่ 1 - ผ่าน Command Line

หากบน Mac หรือ Linux ให้สั่งดังนี้บน Terminal

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

หรือถ้าบน Windows ให้สั่งดังนี้บน Command Prompt

keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64

นำค่าที่ได้มาใส่ทั้งในช่อง Development Key Hashes และ Release Key Hash

และสร้าง Key Hash สำหรับ Deployment Keystore เพื่อให้แอพฯในเวอร์ชั่น Production สามารถเชื่อมต่อกับ Facebook App ได้

keytool --exportcert -alias ENTER_ALIAS_HERE -keystore PATH_TO_KEYSTORE.keystore | openssl sha1 -binary | openssl base64

นำค่าที่ได้ไปใส่ไว้ในช่อง Release Key Hash

วิธีที่ 2 - ผ่าน Java Code

อย่างไรก็ตามหากเครื่องของท่านไม่ได้ติดตั้ง keytool หรือ openssl ไว้ ท่านสามารถสร้าง Key Hash ดังกล่าวผ่าน Java Code ได้ดังนี้ (เปลี่ยนชื่อ Package ให้ตรงกับแอพฯของท่านด้วย)

        try {
            PackageInfo info = getPackageManager().getPackageInfo(
                    "com.inthecheesefactory.lab.facebooklike",
                    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) {

        }

โดยครั้งแรกรันผ่าน Android Studio แล้วก็อปปี้ Key มาใส่ทั้งช่อง Development Key Hashes และ Release Key Hash ส่วนอีกครั้งให้ Sign APK ด้วย Keystore สำหรับการเอาขึ้น Store แล้วนำ APK ที่ Sign เสร็จแล้วไปรันบนเครื่องเพื่อดึงค่า Key Hash มาผ่าน logcat เพื่อนำมาใส่ในช่อง Release Key Hash

ทั้งนี้หากต้องการสร้าง Key Hash สำหรับ Production สามารถทำตอนหลังได้ ที่สำคัญสำหรับการทดสอบ ณ ตอนนี้คือต้องใส่ Development Key Hash ที่ได้จาก debug.keystore ทั้งในช่อง Development Key Hashes และ Release Key Hash ให้เรียบร้อยครับ

keyhashes2

กดบันทึกให้เรียบร้อย จากนั้นเลื่อนมาด้านล่างแล้วกด Skip to Developer Dashboard เพื่อเข้าสู่หน้า Dashboard ของแอพฯที่เพิ่งสร้างขึ้น

skiptodashboard

จากนั้นก็อปปี้ App ID เอาไว้เพื่อใช้ในขั้นตอนต่อไปครับ

appid

เรียบร้อยสำหรับการสร้าง Facebook App เบื้องต้น

ติดตั้ง Facebook SDK และตั้งค่าโปรเจค

ฝั่ง Facebook เสร็จแล้ว ย้ายมาติดตั้งฝั่งแอพฯแอนดรอยด์บ้าง เริ่มต้นจากใส่ Dependency เข้าไปในโปรเจคให้เรียบร้อย

dependencies {
    compile 'com.facebook.android:facebook-android-sdk:4.0.1'
}

ใส่ค่า Facebook Application ID เข้าไปใน String Resource (เปลี่ยนตัวเลขด้านในให้ตรงกับ App ID ของท่าน)

<string name="app_id">1459806660978042</string>

แปะโค้ดดังต่อไปนี้ใน AndroidManifest.xml ก่อนปิด tag </application> พร้อมแก้ตัวเลขที่ต่อท้าย FacebookContentProvider ให้เป็น App ID ของท่าน

        <!-- Facebook -->
        <activity android:name="com.facebook.FacebookActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name" />
        <meta-data android:name="com.facebook.sdk.ApplicationName"
            android:value="@string/app_name" />
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/>

        <provider android:authorities="com.facebook.app.FacebookContentProvider1459806660978042"
            android:name="com.facebook.FacebookContentProvider"
            android:exported="true"/>

การใช้งาน LikeView จำเป็นต้องใช้ Permission INTERNET ด้วย ดังนั้นใส่ Permission ให้เรียบร้อยในไฟล์ AndroidManifest.xml ก่อนเปิด tag <application>

<uses-permission android:name="android.permission.INTERNET"/>

หากยังไม่ได้สร้างคลาส Custom Application ของตัวเองให้ทำให้เรียบร้อยแล้วแปะโค้ดด้านล่างนี้ภายในฟังก์ชั่น onCreate เพื่อ Initialize Facebook SDK

public class MainApplication extends Application {

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

        FacebookSdk.sdkInitialize(getApplicationContext());
   }
}

และเช็คให้เรียบร้อยด้วยว่าผูก Custom Application เข้ากับ AndroidManifest.xml แล้ว

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name=".MainApplication" >

เป็นอันเรียบร้อยครับ

เล่นกับปุ่ม LikeView

ตอนนี้แอพฯเราก็พร้อมใช้งานปุ่ม LikeView แล้ว เรามาเริ่มลองเล่นกันเลยด้วยการแปะ LikeView ลงไปใน Layout

<com.facebook.share.widget.LikeView
        android:id="@+id/likeView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

จากนั้นไปตั้งค่าการใช้งานผ่าน Java Code ดังนี้

LikeView likeView = (LikeView) findViewById(R.id.likeView);
likeView.setLikeViewStyle(LikeView.Style.STANDARD);      
likeView.setAuxiliaryViewPosition(LikeView.AuxiliaryViewPosition.INLINE);

และกำหนด url ของปุ่ม Like ด้วยคำสั่ง setObjectIdAndType

likeView.setObjectIdAndType(
        "http://inthecheesefactory.com/blog/understand-android-activity-launchmode/en",
        LikeView.ObjectType.OPEN_GRAPH)

ผลการทำงานคือปุ่ม Like ใช้งานได้เรียบร้อย

exp0

อย่างไรก็ตาม มันยังไม่สมบูรณ์แบบเพราะพบปัญหาดังต่อไปนี้

ปัญหาที่พบ 1: ไม่ขึ้นแสดงจำนวนและสถานะการ Like จนกว่าเราจะกด Like แล้วเท่านั้น

ปัญหาที่พบ 2: ใช้บนเครื่องที่ไม่ได้ลง Facebook ไม่ได้

exp1

ทั้งนี้เพราะปุ่ม LikeView จะทำงานได้เต็มฟังก์ชั่นก็ต่อเมื่อแอพฯเชื่อมต่อกับ Facebook App ไว้แล้วเท่านั้น ต่างกับปุ่ม Like บนเว็บที่สามารถแสดงผลข้อมูลจำนวนการ Like ได้ทันทีแม้จะไม่ได้ Login Facebook ไว้

onweb

ด้วยเหตุผลนี้เราจึงต้องเปลี่ยน Flow การทำงานนิดหน่อยว่า ถ้าแอพฯยังไม่ได้เชื่อมต่อกับ Facebook App ให้ซ่อนปุ่ม Like ไว้แล้วแสดงปุ่ม Login แทนเพื่อบังคับให้เชื่อมต่อกับ Facebook ก่อนจะใช้งานปุ่ม Like ได้ เมื่อ Login เสร็จแล้วก็ค่อยแสดงปุ่ม Like ขึ้นมา

เทคนิคไม่มีอะไรซับซ้อน เนียนสร้างปุ่ม Login ขึ้นมาหนึ่งตัวให้หน้าตาคล้ายกับปุ่ม Like ด้วย LinearLayout แล้วจับมาอยู่กับ LikeView ด้วย RelativeLayout

...
<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <!-- Login Button in the same style as LikeView -->
    <LinearLayout
        android:id="@+id/btnLoginToLike"
        android:background="@drawable/com_facebook_button_like_background"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:clickable="true" >

        <ImageView
            android:src="@drawable/com_facebook_button_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginTop="7.5dp"
            android:layout_marginBottom="7.5dp"/>

        <TextView
            android:id="@+id/tvLogin"
            android:text="Login"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="8dp"
            android:textColor="@android:color/white"
            android:textStyle="bold"
            android:layout_gravity="center_vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <com.facebook.share.widget.LikeView
        android:id="@+id/likeView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>
...

จากนั้นเชื่อมลอจิคเข้าด้วยกันด้วย Java Code โดยใช้ LoginManager, CallbackManager และ AccessToken ของ Facebook SDK for Android มาช่วยจัดการเรื่องการ Login และเช็คสถานะ

public class MainActivity extends Activity {
    
    LinearLayout btnLoginToLike;
    LikeView likeView;
    CallbackManager callbackManager;

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

        initInstances();
        initCallbackManager();
        refreshButtonsState();
    }

    private void initInstances() {
        btnLoginToLike = (LinearLayout) findViewById(R.id.btnLoginToLike);
        likeView = (LikeView) findViewById(R.id.likeView);
        likeView.setLikeViewStyle(LikeView.Style.STANDARD);
        likeView.setAuxiliaryViewPosition(LikeView.AuxiliaryViewPosition.INLINE);

        btnLoginToLike.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("public_profile"));
            }
        });
    }

    private void initCallbackManager() {
        callbackManager = CallbackManager.Factory.create();
        LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                refreshButtonsState();
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onError(FacebookException e) {

            }
        });
    }

    private void refreshButtonsState() {
        if (!isLoggedIn()) {
            btnLoginToLike.setVisibility(View.VISIBLE);
            likeView.setVisibility(View.GONE);
        } else {
            btnLoginToLike.setVisibility(View.GONE);
            likeView.setVisibility(View.VISIBLE);
        }
    }

    public boolean isLoggedIn() {
        return AccessToken.getCurrentAccessToken() != null;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // Handle Facebook Login Result
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }
}

เป็นอันเรียบร้อย มาดูผลการทำงานกัน =)

ผลการทำงาน

เมื่อยังไม่ได้เชื่อมต่อแอพฯเข้ากับ Facebook ปุ่ม Like จะถูกแสดงเป็นปุ่ม Login แทน

btnLogin2

และกดปุ่ม Login ก็จะเข้ากระบวนการ Login ตามปกติ

loginprocess

เมื่อ Login เสร็จ ปุ่ม Like จะแสดงจำนวน Like และสถานะการ Like ทันที หลังจากนี้หากเปลี่ยน url ตัว Facebook SDK ก็จะโหลดจำนวนล่าสุดมาแสดงด้วยทุกครั้ง กลายเป็นปุ่มที่ทำงานโดยสมบูรณ์เหมือนบนเว็บครับ

loggedin

เมื่อกด Like บนแอพฯ สถานะและตัวเลขการกด Like ก็จะเปลี่ยนไปบนเว็บไซต์ด้วยเช่นกัน

liked

ผลพลอยได้ของวิธีนี้คือ ปุ่ม Like จะทำงานได้แม้กระทั่งในมือถือเครื่องที่ไม่มีแอพฯ Facebook ลงไว้ ซึ่งแน่นอนว่าจึงสามารถทำงานบน Chrome หรือบนคอมพ์ผ่าน ARC Welder ได้ด้วยเช่นกัน

arcwelder

บั๊กที่พบ

ถึงแม้จะใช้งานได้เกือบสมบูรณ์แบบแล้ว แต่ปุ่ม LikeView ยังมีบั๊กให้พบเห็นได้อยู่ หนึ่งในนั้นคือถ้าเรากด Like บนเว็บ บางครั้งบนแอพฯจะไม่แสดงสถานะการถูก Like อย่างถูกต้อง คงต้องรอการแก้ไขจากทาง Facebook ครับ

FBLikeAndroid Library

และเช่นเคย เพื่อความสะดวกในการใช้งานเราจึงทำเป็น Library มาให้ใช้กันเรียบร้อยครับสำหรับปุ่ม LikeView ที่มาพร้อมปุ่ม Login ด้วยคุณสมบัติแสดงปุ่ม Login แทนปุ่ม Like หากแอพฯยังไม่ได้เชื่อมต่อกับ Facebook และจะเปลี่ยนเป็นปุ่ม Like โดยอัตโนมัติที่แอพฯเชื่อมต่อกับ Facebook แล้ว

fblikeandroid

การใช้งานทำได้ง่ายๆดังนี้ เริ่มด้วยใส่ Dependency เข้าไปตามด้านล่างนี้

dependencies {
    compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}

สามารถแปะ com.inthecheesefactory.lib.fblike.widget.FBLikeView เพื่อใช้งานใน UI ได้ทันที

<com.inthecheesefactory.lib.fblike.widget.FBLikeView
        android:id="@+id/fbLikeView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

การเข้าถึง LikeView ทำได้ด้วยคำสั่ง getLikeView() การกำหนด URL ของปุ่ม LikeView จึงทำได้ดังนี้

FBLikeView fbLikeView = (FBLikeView) rootView.findViewById(R.id.fbLikeView);
fbLikeView.getLikeView().setObjectIdAndType(
        "http://inthecheesefactory.com/blog/understand-android-activity-launchmode/en",
        LikeView.ObjectType.OPEN_GRAPH);

สุดท้ายใส่คำสั่ง FBLikeView.onActivityResult เข้าไปในทุก Activity ดังนี้ เพื่อเชื่อมต่อปุ่ม FBLikeView ต่างๆเข้ากับระบบ Login ของ Facebook SDK v4

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        FBLikeView.onActivityResult(requestCode, resultCode, data);
    }

เพียงเท่านี้ปุ่ม LikeView ของท่านก็จะใช้งานได้อย่างสมบูรณ์บนแอพฯของท่านแล้วครับ =)

ทั้งนี้หากต้องการตัดการเชื่อมต่อแอพฯจาก Facebook ให้สั่งดังนี้ แล้วทุกปุ่มจะกลับไปสู่สถานะ Login โดยอัตโนมัติ

FBLikeView.logout();

เป็นอันเสร็จเรียบร้อยครับ ใช้งานง่ายดีใช่ม้าาา =)

Source Code ของ Library นี้อยู่ที่ https://github.com/nuuneoi/FBLikeAndroid ครับ สามารถเข้าไปดูหรือช่วย Contribute ได้ทุกเมื่อครับ =)

ยื่นขออนุมัติให้ทุกคนใช้ LikeView ได้

เพื่อที่จะให้ LikeView ถูกเอาไปใช้งานจริงได้ในแอพฯ Production เราจำเป็นต้องยื่นขออนุมัติการใช้ LikeView จากทาง Facebook ก่อนด้วยขั้นตอนดังต่อไปนี้

1) เข้าหน้า App Details แล้วใส่ Long Description, Privacy Policy URL และ App Icon ให้เรียบร้อย

appdetails

2) เข้าหน้า Status & Review ของ Facebook App ที่สร้างขึ้น แล้วกด Start a Submission

submission1

3) ติ๊กถูกที่ Native Like Button แล้วกด Add 1 Item

submission2

4) กด Add Notes หลัง Native Like Button เพื่อใส่ขั้นตอนการใช้งานปุ่ม LikeView ภายในแอพฯแบบ Step by Step จะให้ดีทำเป็นภาพแล้วแนบเป็นลิงค์ไปจะได้ผลดีที่สุด

AddNotes

5) อัพโหลดไฟล์ apk, ใส่ Screenshots, เลือกที่ I have tested that my application loads on all of the above platforms แล้วกดที่ Submit for Review

submission3

6) เข้าไปใส่ Contact Email ในหน้า Settings

submission4

7) จบด้วยการเปิด Public ให้เป็น On ในหน้า Status & Review

submission5

จากนั้นรอให้ Facebook อนุมัติ Native Like Button ใช้เวลาประมาณ 1-2 วันครับ โดยเฉลี่ยจะต้องใช้ 2-3 ครั้งถึงจะอนุมัติผ่าน ดังนั้นเผื่อเวลาไว้หน่อยครับ

หากผ่านแล้ว หน้าตาหน้า Status & Review จะเป็นประมาณนี้ครับ

submissionpassed

ซึ่งถ้าเห็นหน้าตาแบบนี้แล้ว แปลว่าปุ่ม LikeView จะใช้งานได้กับทุกคนเรียบร้อยแล้ว =)

หวังว่าบทความเล็กๆนี้จะมีประโยชน์ต่อแอพฯของท่านครับ สวัสดีครับ =)

ผู้เขียน: nuuneoi (Android GDE, CTO & CEO at The Cheese Factory)
นักพัฒนาแบบ Full-Stack ที่มีประสบการณ์ในการพัฒนาแอพฯแอนดรอยด์มากว่า 6 ปีและอยู่ในวงการพัฒนาแอพฯมือถือมากว่า 12 ปี มีความสนใจทางด้าน Infrastucture, Service Side, Design, UI&UX, Hardware, Optimization, Cooking, Photographing, Blogging, Training, Public Speaking และรักที่จะแชร์เรื่องราวให้ผู้คนได้อ่านได้ฟังกันผ่าน Blog