ปุ่ม Like ถือเป็นหนึ่งในสิ่งที่แทบทุกเว็บต้องมีไว้เพื่อเพิ่ม Reach ของเว็บ พอมาอยู่ในยุคที่ Traffic จำนวนมากมาจาก Mobile จึงไม่ต้องแปลกใจที่ Facebook จึงจัดปุ่ม Like แบบ Native อย่าง LikeView
มาให้เราใช้แปะลงไปในแอพฯเรียบร้อย
อย่างไรก็ตาม การแปะ 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 ใหม่
ใส่ชื่อ Facebook App ที่ต้องการแล้วกด Create New Facebook App ID
เลือก Category แล้วกด Create App ID
จะเข้าสู่หน้าตั้งค่า Facebook App ให้ Scroll ลงไปล่างสุดพร้อมใส่ชื่อ Package และชื่อ Class Activity หลักของแอพฯแล้วกด Next
จากนั้นเราต้องสร้าง Key Hash สำหรับ Debug Keystore เพื่อให้แอพฯในโหมด Debug เราสามารถใช้งานร่วมกับ Facebook App ที่สร้างขึ้นได้ และต้องใส่ Release Key Hash เพื่อให้แอพฯบน Production สามารถใช้งานได้
วิธีที่ 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 ให้เรียบร้อยครับ
กดบันทึกให้เรียบร้อย จากนั้นเลื่อนมาด้านล่างแล้วกด Skip to Developer Dashboard เพื่อเข้าสู่หน้า Dashboard ของแอพฯที่เพิ่งสร้างขึ้น
จากนั้นก็อปปี้ App ID เอาไว้เพื่อใช้ในขั้นตอนต่อไปครับ
เรียบร้อยสำหรับการสร้าง 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 ใช้งานได้เรียบร้อย
อย่างไรก็ตาม มันยังไม่สมบูรณ์แบบเพราะพบปัญหาดังต่อไปนี้
ปัญหาที่พบ 1: ไม่ขึ้นแสดงจำนวนและสถานะการ Like จนกว่าเราจะกด Like แล้วเท่านั้น
ปัญหาที่พบ 2: ใช้บนเครื่องที่ไม่ได้ลง Facebook ไม่ได้
ทั้งนี้เพราะปุ่ม LikeView จะทำงานได้เต็มฟังก์ชั่นก็ต่อเมื่อแอพฯเชื่อมต่อกับ Facebook App ไว้แล้วเท่านั้น ต่างกับปุ่ม Like บนเว็บที่สามารถแสดงผลข้อมูลจำนวนการ Like ได้ทันทีแม้จะไม่ได้ Login Facebook ไว้
ด้วยเหตุผลนี้เราจึงต้องเปลี่ยน 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 แทน
และกดปุ่ม Login ก็จะเข้ากระบวนการ Login ตามปกติ
เมื่อ Login เสร็จ ปุ่ม Like จะแสดงจำนวน Like และสถานะการ Like ทันที หลังจากนี้หากเปลี่ยน url ตัว Facebook SDK ก็จะโหลดจำนวนล่าสุดมาแสดงด้วยทุกครั้ง กลายเป็นปุ่มที่ทำงานโดยสมบูรณ์เหมือนบนเว็บครับ
เมื่อกด Like บนแอพฯ สถานะและตัวเลขการกด Like ก็จะเปลี่ยนไปบนเว็บไซต์ด้วยเช่นกัน
ผลพลอยได้ของวิธีนี้คือ ปุ่ม Like จะทำงานได้แม้กระทั่งในมือถือเครื่องที่ไม่มีแอพฯ Facebook ลงไว้ ซึ่งแน่นอนว่าจึงสามารถทำงานบน Chrome หรือบนคอมพ์ผ่าน ARC Welder ได้ด้วยเช่นกัน
บั๊กที่พบ
ถึงแม้จะใช้งานได้เกือบสมบูรณ์แบบแล้ว แต่ปุ่ม LikeView ยังมีบั๊กให้พบเห็นได้อยู่ หนึ่งในนั้นคือถ้าเรากด Like บนเว็บ บางครั้งบนแอพฯจะไม่แสดงสถานะการถูก Like อย่างถูกต้อง คงต้องรอการแก้ไขจากทาง Facebook ครับ
FBLikeAndroid Library
และเช่นเคย เพื่อความสะดวกในการใช้งานเราจึงทำเป็น Library มาให้ใช้กันเรียบร้อยครับสำหรับปุ่ม LikeView ที่มาพร้อมปุ่ม Login ด้วยคุณสมบัติแสดงปุ่ม Login แทนปุ่ม Like หากแอพฯยังไม่ได้เชื่อมต่อกับ Facebook และจะเปลี่ยนเป็นปุ่ม Like โดยอัตโนมัติที่แอพฯเชื่อมต่อกับ Facebook แล้ว
การใช้งานทำได้ง่ายๆดังนี้ เริ่มด้วยใส่ 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 ให้เรียบร้อย
2) เข้าหน้า Status & Review ของ Facebook App ที่สร้างขึ้น แล้วกด Start a Submission
3) ติ๊กถูกที่ Native Like Button แล้วกด Add 1 Item
4) กด Add Notes หลัง Native Like Button เพื่อใส่ขั้นตอนการใช้งานปุ่ม LikeView ภายในแอพฯแบบ Step by Step จะให้ดีทำเป็นภาพแล้วแนบเป็นลิงค์ไปจะได้ผลดีที่สุด
5) อัพโหลดไฟล์ apk, ใส่ Screenshots, เลือกที่ I have tested that my application loads on all of the above platforms แล้วกดที่ Submit for Review
6) เข้าไปใส่ Contact Email ในหน้า Settings
7) จบด้วยการเปิด Public ให้เป็น On ในหน้า Status & Review
จากนั้นรอให้ Facebook อนุมัติ Native Like Button ใช้เวลาประมาณ 1-2 วันครับ โดยเฉลี่ยจะต้องใช้ 2-3 ครั้งถึงจะอนุมัติผ่าน ดังนั้นเผื่อเวลาไว้หน่อยครับ
หากผ่านแล้ว หน้าตาหน้า Status & Review จะเป็นประมาณนี้ครับ
ซึ่งถ้าเห็นหน้าตาแบบนี้แล้ว แปลว่าปุ่ม 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
|