Tích hợp mạng xã hội vào ứng dụng Android (Google) - Phần 2
Khóa học lập trình Android cơ bản
Danh sách bài học
Tích hợp mạng xã hội vào ứng dụng Android (Google) - Phần 2
Dẫn nhập
Trong các bài học trước, chúng ta đã cùng nhau tìm hiểu về cách tạo file google-services.json, cách thiết lập để CHUẨN BỊ TÍCH HỢP GOOGLE VÀO ỨNG DỤNG ANDROID.
Ở bài học này chúng ta sẽ tiếp tục hoàn thành phần cuối của bài TÍCH HỢP MẠNG XÃ HỘI GOOGLE.
Nội dung
Để đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về các phần:
- CẤU TRÚC CƠ BẢN MỘT CHƯƠNG TRÌNH ANDROID.
- Có tài khoản Google.
- Đã hoàn thành bài TÍCH HỢP MẠNG XÃ HỘI VÀO ỨNG DỤNG ANDROID (Google) – Phần 1.
Trong bài học này, chúng ta sẽ cùng tìm hiểu các vấn đề:
- Tiến hành code chính, tích hợp chức năng đăng nhập và đăng xuất Google.
Tích hợp Google cho ứng dụng trong Android Studio
Bước 1: Chúng ta sẽ thêm các thành phần sau lần lượt vào các file build.gradle :
File build.gradle cấp ngoài cùng:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
File build.gradle trong thư mục app/
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.howkteam.googleexample"
minSdkVersion 13
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.google.android.gms:play-services-auth:9.8.0'
testCompile 'junit:junit:4.12'
}
apply plugin: 'com.google.gms.google-services'
Bước 2: Chúng ta thêm nút đăng nhập Google như sau. Cũng như Facebook SDK, Google Auth cũng đã cung cấp sẵn cho chúng ta một button như vậy:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.howkteam.googleexample.MainActivity">
<com.google.android.gms.common.SignInButton
android:id="@+id/sign_in_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/sign_out_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sign out"/>
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Bước 3: Tiếp đến là file MainActivity.java. Quá trình làm việc với Google Sign-in phức tạp hơn Facebook một chút, đặc biệt là ở phần cache (đệm dữ liệu làm việc). Tuy nhiên may thay nó chỉ là phần phụ, và những thành phần chính chúng ta cần là:
private static final String TAG = "SignInActivity";
private static final int RC_SIGN_IN = 9001;
private GoogleApiClient mGoogleApiClient;
private TextView mStatusTextView;
private ProgressDialog mProgressDialog;
Ở trên chúng ta có lần lượt:
- Biến TAG để chỉ ra tên mô tả của Activity.
- Result code để kiểm tra kết quả trả về của Activity sign in.
- Biến GoogleApiClient đại diện cho client Google (chính là ứng dụng của bạn).
- TextView để xem trạng thái đăng nhập.
- ProgressDialog để tạo hiệu ứng chờ đăng nhập.
Bước 4: Chúng ta thêm đoạn code sau ở dưới setContentView trong hàm onCreate:
mStatusTextView = (TextView) findViewById(R.id.status);
// Button listeners
findViewById(R.id.sign_in_button).setOnClickListener(this);
findViewById(R.id.sign_out_button).setOnClickListener(this);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton.setSize(SignInButton.SIZE_STANDARD);
signInButton.setScopes(gso.getScopeArray());
Trước đó, cần implement một vài interface cho MainActivity:
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.OnConnectionFailedListener,
View.OnClickListener
Dừng lại một chút để mình giải thích.
- GoogleSignInOptions: Đoạn này sử dụng builder để tạo các tùy chọn yêu cầu quyền truy cập khi đăng nhập. Ở đây chỉ bao gồm thông tin cơ bản (ID, tên, thông tin chung) định nghĩa trong DEFAULT_SIGN_IN; và email (hàm requestEmail).
- Google API Client: Như đã đề cập ở bước 3, cài đặt cho ứng dụng tự động quản lý API, và chỉ sử dụng api là Google Sign In, với Sign In Options là gso.
- SignInButton: Cài đặt kích cỡ và đặt các scope quyền ngay trong nút sign in, scope này có thể do mình tự truyền vào dưới dạng ArrayList hoặc lấy ra từ biến gso thông qua hàm getScopeArray.
Bước 5: Hẳn khi viết ứng dụng, chúng ta đều không muốn người dùng phải lặp đi lặp lại thao tác đăng nhập. Vì thế không gì hay hơn là cài đặt sẵn một cơ chế giúp thông tin đăng nhập được lưu lại sau khi đăng nhập thành công.
Để làm được điều này, Google cũng đã cung cấp cho chúng ta một giải pháp là OptionalPendingResult. Chúng ta có hàm handleSignInResult:
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Đã đăng nhập thành công, hiển thị trạng thái đăng nhập.
GoogleSignInAccount acct = result.getSignInAccount();
mStatusTextView.setText(acct.getDisplayName());
} else {
// Đã đăng xuất, hiển thị trạng thái đăng xuất.
mStatusTextView.setText("Signed out");
}
}
Tiếp đến, chúng ta override hàm onStart:
@Override
protected void onStart() {
super.onStart();
OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
// Nếu dữ liệu của người dùng trong bộ d dệm hợp lệ, OptionalPendingResult sẽ ở trạng thái "done"
// và GoogleSignInResult sẽ có ngay mà không cần thực hiện đăng nhập lại.
Log.d(TAG, "Got cached sign-in");
GoogleSignInResult result = opr.get();
handleSignInResult(result);
} else {
// Nếu người dùng chưa từng đăng nhập trước đó, hoặc phiên làm việc đã hết hạn,
// thao tác bất đồng bộ này sẽ ngầm đăng nhập người dùng, và thực hiện thao tác cross sign-on.
showProgressDialog();
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
@Override
public void onResult(GoogleSignInResult googleSignInResult) {
hideProgressDialog();
handleSignInResult(googleSignInResult);
}
});
}
}
Bước 6: Cài đặt hàm onClick (implement từ View.OnClickListener):
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.sign_in_button:
signIn();
break;
case R.id.sign_out_button:
signOut();
break;
}
}
Bước 7: Override hàm onConnectionFailed, hàm này hiện không làm gì ngoài thông báo log:
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed:" + connectionResult);
}
Bước 8: Override hàm onActivityResult để lấy kết quả trả về từ Google Sign in và xử lý kết quả đó bằng hàm handleSignInResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
}
}
Bước 9: Tạo hàm SignIn, hàm này có tác dụng chuyển hướng ứng dụng đến intent chứa các thao tác đăng nhập Google:
private void signIn() {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
Bước 10: Hàm SignOut, hàm này sẽ xóa phiên đăng nhập của Google trên ứng dụng:
private void signOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
mStatusTextView.setText("Signed out");
Toast.makeText(MainActivity.this, "Signed out", Toast.LENGTH_SHORT).show();
}
});
}
Bước 11: Tạo 2 hàm ẩn / hiện để xử lý ProgressDialog:
private void showProgressDialog() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Loading");
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
}
private void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.hide();
}
}
Class MainActivity.java đầy đủ như sau:
package com.howkteam.googleexample;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.OptionalPendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.OnConnectionFailedListener,
View.OnClickListener {
private static final String TAG = "SignInActivity";
private static final int RC_SIGN_IN = 9001;
private GoogleApiClient mGoogleApiClient;
private TextView mStatusTextView;
private ProgressDialog mProgressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStatusTextView = (TextView) findViewById(R.id.status);
// Button listeners
findViewById(R.id.sign_in_button).setOnClickListener(this);
findViewById(R.id.sign_out_button).setOnClickListener(this);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton.setSize(SignInButton.SIZE_STANDARD);
signInButton.setScopes(gso.getScopeArray());
}
@Override
protected void onStart() {
super.onStart();
OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
// Nếu dữ liệu của người dùng trong bộ d dệm hợp lệ, OptionalPendingResult sẽ ở trạng thái "done"
// và GoogleSignInResult sẽ có ngay mà không cần thực hiện đăng nhập lại.
Log.d(TAG, "Got cached sign-in");
GoogleSignInResult result = opr.get();
handleSignInResult(result);
} else {
// Nếu người dùng chưa từng đăng nhập trước đó, hoặc phiên làm việc đã hết hạn,
// thao tác bất đồng bộ này sẽ ngầm đăng nhập người dùng, và thực hiện thao tác cross sign-on.
showProgressDialog();
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
@Override
public void onResult(GoogleSignInResult googleSignInResult) {
hideProgressDialog();
handleSignInResult(googleSignInResult);
}
});
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.sign_in_button:
signIn();
break;
case R.id.sign_out_button:
signOut();
break;
}
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed:" + connectionResult);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
}
}
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Đã đăng nhập thành công, hiển thị trạng thái đăng nhập.
GoogleSignInAccount acct = result.getSignInAccount();
mStatusTextView.setText(acct.getDisplayName());
} else {
// Đã đăng xuất, hiển thị trạng thái đăng xuất.
mStatusTextView.setText("Signed out");
}
}
private void signIn() {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
private void signOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
mStatusTextView.setText("Signed out");
Toast.makeText(MainActivity.this, "Signed out", Toast.LENGTH_SHORT).show();
}
});
}
private void showProgressDialog() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Loading");
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
}
private void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.hide();
}
}
}
Bước 12: Chạy thử ứng dụng
- Khi vào ứng dụng:
- Khi nhấn nút Sign in:
- Sau khi chọn account hoặc đăng nhập xong:
Source code tham khảo
Nhằm giúp các bạn thao tác dễ dàng hơn trong quá trình theo dõi bài viết, Kteam hỗ trợ source code tham khảo ngay trong link bên dưới
Kết luận
Qua bài này chúng ta đã nắm được cách tích hợp Google Sign in vào ứng dụng để lấy thông tin, xử lý thông tin trả về qua Google API trên Android.
Chúng ta sẽ tiến hành tích hợp GCM, cũng là một phần của Google API, thực hiện gửi tin nhắn qua GOOGLE CLOUD MESSAGING & PUSH NOTIFICATION
Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.
Tải xuống
Tài liệu
Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Tích hợp mạng xã hội vào ứng dụng Android (Google) - Phần 2 dưới dạng file PDF trong link bên dưới.
Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com
Đừng quên like và share để ủng hộ Kteam và tác giả nhé!
Thảo luận
Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.
Nội dung bài viết
Tác giả/Dịch giả
Khóa học
Khóa học lập trình Android cơ bản
Serial tutorial hướng dẫn lập trình Android cơ bản
Chạy app bị lỗi rồi ad ơi