Devahoy Logo
PublishedAt

Android

สร้าง Facebook Login ด้วย Android Studio

สร้าง Facebook Login ด้วย Android Studio

จากบทความที่แล้ว เขียนเกี่ยวกับ Facebook SDK for Android สร้างปุ่ม Login โดยใช้ Eclipse กันไป วันนี้ก็เลยมาเขียนบทความโดยใช้ Android Studio ครับ เผื่อบางคนใช้ Android Studio แล้วงงๆ กับตอน import Library Facebook จากบทความก่อน ผมจะข้าม Step1 ไปเลยครับเนื่องจากเป็นการเตรียมตัว การ Setup ซึ่งเหมือนกัน มาเริ่มที่ Step 2 การ สร้างโปรเจ็คเลย

เริ่มสร้างโปรเจ็ค

เริ่มทำการสร้างโปรเจ็คใน Android Studio กันเลยครับ คิดว่าทุกคนคงสร้างกันเป็น ก็ดูตามภาพไปเลยครับ หากไม่เป็นจริงๆ ก็อ่านนี้ สร้างโปรเจ็คด้วย Android Studio

Create New Project

โปรเจ็คใหม่ ผมตั้งชื่อตามนี้ละกัน

  • Application Name : AhoyFacebookLogin
  • Module Name : app
  • Package Name : com.devahoy.facebooksdk.sample
  • Project Location : เลือก path ที่จะเก็บ Project
  • Minimum/ Target SDK : อันนี้เลือกตามสะดวกครับ ผมเลือก min: 11, Target: 17, Compile: 19

Choose launcher icon

Create New Project 3

Create New Project 4

เมื่อทำการสร้างโปรเจ็คเสร็จแล้ว ก็จะได้ไฟล์ MainActivity.java และ activity_main.xml ซึ่งเหมาะกับมือใหม่ดี จะได้ไม่ต้องงงๆกับ fragment เหมือนอย่างตอนสร้างโปรเจ็คใหม่บน Eclipse ครับ :)

Import Facebook Library

ทำการ import module ของ Facebook SDK ที่ดาวน์โหลดมา ลองดู Step1: เตรียมเครื่องมือ ประกอบครับ หรือหากต้องการโหลด Facebook SDK for Android โดยตรง ก็โหลดตามนี้ ปัจจุบันเวอร์ชั่น 3.14 แล้ว

กลับมาที่โปรเจ็คของ Android Studio คลิ๊กขวา -> เลือก New -> Module จากนั้นเลือก Import Existing Project

Import Existing Project

ที่ source directory เลือกไปยัง Facebook SDK ที่ดาวน์โหลดมา (ต้องทำการแตกไฟล์zip ออกมาซะก่อนนะ)

Source Directory

สังเกตว่าเลือก folder facebook ภายในโฟลเดอร์ facebook-android-sdk-3.14 อีกที

จะได้แบบนี้ คลิ๊ก Finish

Source Directory2

เมื่อทำการ import Library เสร็จ ปรากฎว่า Gradle build failed ซะงั้น

Gradle Build Failed

จริงๆ หากใครมี Build Tools เวอร์ชั่น 19.0.0 ในเครื่อง มันก็จะไม่ error หรอก แต่พอดีเครื่องนี้ไม่มี จึงทำให้เกิด error เนื่องจาก ไฟล์ build.gradle ของ Facebook SDK นั้นตั้งค่า build tool เป็น 19.0.0

วิธีแก้ก็มี 2 วิธีคือ ดาวน์โหลด Build Tool เวอร์ชั่น 19.0.0 มาซะ ผ่าน Android SDK Manager (แต่ไม่แนะนำ ควรใช้เวอร์ชั่นล่าสุดดีกว่า เวอร์ชั่น 19.0.3) และวิธีที่สอง คือ เปลี่ยนค่าที่ config ไว้ใน build.gradle เป็น 19.0.3 ซะ ดังนี้

เปิด build.gradle ใน facebook

build.gradle file

แล้วแก้เป็นแบบนี้

1
apply plugin: 'android-library'
2
3
dependencies {
4
compile 'com.android.support:support-v4:13.0.+'
5
compile files('libs/bolts.jar')
6
}
7
8
android {
9
compileSdkVersion 19
10
buildToolsVersion "19.0.3"
11
12
defaultConfig {
13
minSdkVersion 8
14
targetSdkVersion 19
15
}
16
17
lintOptions {
18
abortOnError false
19
}
20
21
sourceSets {
22
main {
23
manifest.srcFile 'AndroidManifest.xml'
24
java.srcDirs = ['src']
25
res.srcDirs = ['res']
26
}
27
}
28
}

กด Try Again หรือเข้า Tools -> Android -> Sync Project with Gradle Files เป็นอันเรียบร้อย

จากนั้น ไปที่ app/build.gradle เพื่อทำการเพิ่ม Module Library ของ Facebook ที่เพิ่มมาเมื่อกี้ซะ โดยเพิ่ม compile project(':facebook') ไว้ในแท็ก dependencies ดังนี้

1
dependencies {
2
compile fileTree(include: ['*.jar'], dir: 'libs')
3
compile 'com.android.support:appcompat-v7:19.+'
4
compile project(':facebook')
5
}

หรืออีกวิธีนึง เหมือนกันนั่นแหละ ถ้าไม่ได้ใช้วิธีเพิ่มโค๊ดไปเองใน build.gradle ก็ใช้วิธีเพิ่มแบบ GUI คือ คลิ๊กขวาที่ app เลือก Open Module Settings เลือกไปที่แท็ป dependencies จากนั้นเลือกปุ่ม + -> Module Dependency และก็เลือก :facebook คลิ๊ก apply -> OK

Facebook Module Library

ทำการ Sync Project with Gradle อีกครั้ง

หากใครมีปัญหา gradle ลองเปลี่ยน targetSDKVersion ใน build.gradle ของ facebook ให้เท่ากับหรือน้อยกว่าใน build.gradle ของ app ดูครับ

สร้างปุ่ม Facebook Login

ทำการแก้ไขไฟล์ activity_main.xml โดยเพิ่มโค๊ดด้านล่างนี้ลงไป

1
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2
xmlns:tools="http://schemas.android.com/tools"
3
android:layout_width="match_parent"
4
android:layout_height="match_parent"
5
android:orientation="vertical">
6
7
<com.facebook.widget.LoginButton
8
android:id="@+id/facebookLoginButton"
9
android:layout_width="wrap_content"
10
android:layout_height="wrap_content"
11
android:layout_gravity="center"
12
android:layout_marginTop="50dp" />
13
14
</LinearLayout>

จะได้หน้าตาแบบนี้

Facebook Login

รู้สึกจะมีปัญหาตอน Rendering XML ไม่แ่น่ใจว่าเป็นที่ Facebook SDK เวอร์ชั่น 3.14 หรือไม่ ทำให้ไม่สามารถดู Preview ในหน้า Graphic Layout ไ้ด้ แต่การใช้งานยังคงได้ปกติ

ต่อมา แก้ไขไฟล์ AndroidManifest.xml โดยเพิ่มข้างล่างนี้ลงไป ก่อนปิดแท็ก application

1
<meta-data
2
android:name="com.facebook.sdk.ApplicationId"
3
android:value="@string/app_id" />
4
5
<activity android:name="com.facebook.LoginActivity" />

โดยค่าของ @string/app_id แก้ไขโดยเปิด /res/value/string.xml จากนั้นนำตัวเลขจาก Facebook App มาใส่ครับ

อ้อ อย่าลืมเพิ่ม permission อินเตอร์เนตด้วยละ

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

สุดท้ายไฟล์ AndroidManifest.xml จะได้ประมาณนี้

1
<?xml version="1.0" encoding="utf-8"?>
2
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
package="com.devahoy.facebooksdk.sample" >
4
5
<uses-permission
6
android:name="android.permission.INTERNET" />
7
8
<application
9
android:allowBackup="true"
10
android:icon="@drawable/ic_launcher"
11
android:label="@string/app_name"
12
android:theme="@style/AppTheme" >
13
<activity
14
android:name="com.devahoy.facebooksdk.sample.MainActivity"
15
android:label="@string/app_name" >
16
<intent-filter>
17
<action android:name="android.intent.action.MAIN" />
18
19
<category android:name="android.intent.category.LAUNCHER" />
20
</intent-filter>
21
</activity>
22
23
<meta-data
24
android:name="com.facebook.sdk.ApplicationId"
25
android:value="@string/app_id" />
26
27
<activity android:name="com.facebook.LoginActivity" />
28
</application>
29
30
31
32
</manifest>

ส่วนวิธีการอื่นๆ ก็เหมือนจากบทความที่แล้วเลย เพียงแค่เปลี่ยนเครื่องมือเขียนเท่านั่นเอง อ่านได้ที่นี่

ไฟล์ทั้งหมดก็จะได้แบบนี้ อาจมีความแตกต่างกันบ้างเล็กน้อย เช่น ActionBarActivity ซึ่งเป็นค่าเริ่มต้นเวลาสร้างโปรเจ็คใหม่บท Android Studio ถ้าเป็น Eclipse จะเป็น FragmentActivity แล้วก็ MainFragment ซึ่งถ้าเป็น Android Studio ผมได้ทำการสร้างขึ้นมาเอง ส่วนถ้าเป็น Eclipse ในบทความเก่า จะถูกสร้างมาให้อัตโนมัติชื่อว่า PlaceholderFragment พร้อมกับ fragment_main.xml

โค๊ดทั้งหมด

ไฟล์ MainActivity.java

1
package com.devahoy.facebooksdk.sample;
2
3
import android.content.Intent;
4
import android.os.Bundle;
5
import android.support.v4.app.Fragment;
6
import android.support.v7.app.ActionBarActivity;
7
import android.util.Log;
8
import android.view.LayoutInflater;
9
import android.view.Menu;
10
import android.view.MenuItem;
11
import android.view.View;
12
import android.view.ViewGroup;
13
import android.widget.Toast;
14
15
import com.facebook.Request;
16
import com.facebook.Response;
17
import com.facebook.Session;
18
import com.facebook.SessionState;
19
import com.facebook.UiLifecycleHelper;
20
import com.facebook.model.GraphUser;
21
import com.facebook.widget.LoginButton;
22
23
24
public class MainActivity extends ActionBarActivity {
25
26
private MainFragment mainFragment;
27
28
@Override
29
protected void onCreate(Bundle savedInstanceState) {
30
31
super.onCreate(savedInstanceState);
32
33
if (savedInstanceState == null) {
34
// Add the fragment on initial activity setup
35
mainFragment = new MainFragment();
36
getSupportFragmentManager()
37
.beginTransaction()
38
.add(android.R.id.content, mainFragment)
39
.commit();
40
} else {
41
// Or set the fragment from restored state info
42
mainFragment = (MainFragment) getSupportFragmentManager()
43
.findFragmentById(android.R.id.content);
44
}
45
}
46
47
48
@Override
49
public boolean onCreateOptionsMenu(Menu menu) {
50
// Inflate the menu; this adds items to the action bar if it is present.
51
getMenuInflater().inflate(R.menu.main, menu);
52
return true;
53
}
54
55
@Override
56
public boolean onOptionsItemSelected(MenuItem item) {
57
// Handle action bar item clicks here. The action bar will
58
// automatically handle clicks on the Home/Up button, so long
59
// as you specify a parent activity in AndroidManifest.xml.
60
int id = item.getItemId();
61
if (id == R.id.action_settings) {
62
return true;
63
}
64
return super.onOptionsItemSelected(item);
65
}
66
67
public static class MainFragment extends Fragment {
68
private static final String TAG = MainFragment.class.getName();
69
70
private UiLifecycleHelper uiHelper;
71
72
private Session.StatusCallback callback = new Session.StatusCallback() {
73
@Override
74
public void call(Session session, SessionState state, Exception exception) {
75
onSessionStateChange(session, state, exception);
76
}
77
};
78
79
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
80
if (state.isOpened()) {
81
82
Request request = Request.newMeRequest(session, new Request.GraphUserCallback() {
83
84
@Override
85
public void onCompleted(GraphUser user, Response response) {
86
Toast.makeText(getActivity(),
87
"Hello " + user.getName(),
88
Toast.LENGTH_LONG).show();
89
}
90
});
91
request.executeAsync();
92
93
} else if (state.isClosed()) {
94
Log.i(TAG, "Logged out...");
95
}
96
}
97
98
@Override
99
public void onResume() {
100
super.onResume();
101
102
Session session = Session.getActiveSession();
103
if (session != null &&
104
(session.isOpened() || session.isClosed()) ) {
105
onSessionStateChange(session, session.getState(), null);
106
}
107
108
uiHelper.onResume();
109
}
110
111
@Override
112
public void onActivityResult(int requestCode, int resultCode, Intent data) {
113
super.onActivityResult(requestCode, resultCode, data);
114
uiHelper.onActivityResult(requestCode, resultCode, data);
115
}
116
117
@Override
118
public void onPause() {
119
super.onPause();
120
uiHelper.onPause();
121
}
122
123
@Override
124
public void onDestroy() {
125
super.onDestroy();
126
uiHelper.onDestroy();
127
}
128
129
@Override
130
public void onSaveInstanceState(Bundle outState) {
131
super.onSaveInstanceState(outState);
132
uiHelper.onSaveInstanceState(outState);
133
}
134
135
@Override
136
public void onCreate(Bundle savedInstanceState) {
137
super.onCreate(savedInstanceState);
138
uiHelper = new UiLifecycleHelper(getActivity(), callback);
139
uiHelper.onCreate(savedInstanceState);
140
}
141
142
@Override
143
public View onCreateView(LayoutInflater inflater, ViewGroup container,
144
Bundle savedInstanceState) {
145
View rootView = inflater.inflate(R.layout.activity_main, container,
146
false);
147
148
LoginButton authButton = (LoginButton) rootView.findViewById(R.id.facebookLoginButton);
149
authButton.setFragment(this);
150
return rootView;
151
}
152
}
153
}

ไฟล์ activity_main.java

1
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2
xmlns:tools="http://schemas.android.com/tools"
3
android:layout_width="match_parent"
4
android:layout_height="match_parent"
5
android:orientation="vertical">
6
7
<com.facebook.widget.LoginButton
8
android:id="@+id/facebookLoginButton"
9
android:layout_width="wrap_content"
10
android:layout_height="wrap_content"
11
android:layout_gravity="center"
12
android:layout_marginTop="50dp" />
13
14
</LinearLayout>
Authors
avatar

Chai Phonbopit

เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust

Related Posts