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

0.0 (0 đánh giá)
Tạo bởi Kteam Cập nhật lần cuối 18:06 14-08-2020 25.410 lượt xem 1 bình luận
Tác giả/Dịch giả: Kteam
Học nhanh

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:

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:

Tích hợp mạng xã hội vào ứng dụng Android (Google) - Phần 2

  • Khi nhấn nút Sign in:

Tích hợp mạng xã hội vào ứng dụng Android (Google) - Phần 2

  • Sau khi chọn account hoặc đăng nhập xong:

Tích hợp mạng xã hội vào ứng dụng Android (Google) - Phần 2


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 

GoogleExample.zip


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 likeshare để ủ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

Đánh giá

Bình luận

Để bình luận, bạn cần đăng nhập bằng tài khoản Howkteam.

Đăng nhập
Phạm Nguyễn Tuấn Thông đã bình luận 21:28 18-06-2018

Chạy app bị lỗi rồi ad ơi

 

Không có video.