Hướng dẫn tích hợp Google Drive vào ứng dụng từ A-Z – Phần 3

0
57
Bài này thuộc phần 3 của 3 phần trong series Hướng dẫn tích hợp Google Drive vào ứng dụng Android

Đây là phần cuối cùng trong series hướng dẫn tích hợp Google Drive SDK vào ứng dụng Android. Như 2 phần trước, mình đã hướng dẫn các bạn đăng kí với Google Drive và bắt đầu cấu hình trên ứng dụng.

Ở phần 2, chúng ta đã code được một phần cho tính năng download tệp từ tài khoản Google Drive của người dùng.  Phần này mình sẽ tiếp tục hoàn thành nốt tính năng:

  • Lựa chọn tệp trong Google Drive để người dùng tải về
  • Xử lý khi người dùng đăng nhập và đăng xuất

Chúng ta tiếp tục nhé

hướng dẫn tích hợp google drive

Hướng dẫn tích hợp Google Drive vào ứng dụng Android

Có khá nhiều bước trong phần này, khi theo dõi có phần nào thắc mắc hoặc có góp ý cho mình thì hãy cmt bên dưới nhé. Dưới đây là hướng dẫn tích hợp google drive SDK

#1. Tạo hội thoại để chọn tệp tải về (Picker Dialog)

Để làm được điều này, chúng ta sử dụng OpenFileActivityOptions API có sẵn của Google Drive SDK.

/**
 * Prompts the user to select a text file using OpenFileActivity.
 *
 * @return Task that resolves with the selected item's ID.
 */
fun pickFiles(driveId: DriveId?) {
  val builder = OpenFileActivityOptions.Builder()
  if (config.mimeTypes != null) {
    builder.setMimeType(config.mimeTypes)
  } else {
    builder.setMimeType(documentMimeTypes)
  }
  if (config.activityTitle != null && config.activityTitle.isNotEmpty()) {
    builder.setActivityTitle(config.activityTitle)
  }
  if (driveId != null) {
    builder.setActivityStartFolder(driveId)
  }
  val openOptions = builder.build()
  pickItem(openOptions)
}

Phần cấu hình cho Picker Dialog này, chúng ta cần truyền vào mimeType, tiêu đề cho Dialog và thư mục mặc định.

Tiếp đến, đến phần lựa chọn tệp, chính là hàm pickItem(), chúng ta làm như sau:

private fun pickItem(openOptions: OpenFileActivityOptions) {
  val openTask = driveClient?.newOpenFileActivityIntentSender(openOptions)
  openTask?.let {
    openTask.continueWith { task ->
      ActivityCompat.startIntentSenderForResult(activity, task.result, REQUEST_CODE_OPEN_ITEM,
          null, 0, 0, 0, null)
    }
  }
}

Phần chọn file thì phía ứng dụng của chúng ta không làm mà sẽ đẩy việc cho Google Drive SDK thông qua hàm: startIntentSenderForResult(). Sau khi chọn xong thì trả lại kết quả tại hàm onActivityResult()

#2. Xử lý khi người dùng đăng nhập/đăng xuất khỏi tài khoản Google Drive

Bạn viết một hàm để kiểm tra xem người dùng đã đăng nhập vào Google Drive rồi hay chưa. Mỗi lần khởi động ứng dụng đều phải gọi hàm này để kiểm tra

fun checkLoginStatus() {
  val requiredScopes = HashSet<Scope>(2)
  requiredScopes.add(Drive.SCOPE_FILE)
  requiredScopes.add(Drive.SCOPE_APPFOLDER)
  signInAccount = GoogleSignIn.getLastSignedInAccount(activity)
  val containsScope = signInAccount?.grantedScopes?.containsAll(requiredScopes)
  val account = signInAccount
  if (account != null && containsScope == true) {
    initializeDriveClient(account)
  }
}

Nếu người dùng đã đăng nhập trước đó, bạn gọi hàm initializeDriveClient() để người dùng có thể sử dụng được luôn mà không cần đăng nhập lại.

Trường hợp nếu người dùng chưa đăng nhập hoặc đã đăng xuất trước đó thì cần phải yêu cầu người dùng xác thực lại

fun auth() {
  activity.startActivityForResult(googleSignInClient.signInIntent,
      REQUEST_CODE_SIGN_IN)
}

Cuối cùng là hàm để người dùng có thể đăng xuất

fun logout() {
  googleSignInClient.signOut()
  signInAccount = null
}

#3. Cập nhật trạng thái đăng nhập trên giao diện ứng dụng

Các bạn mở lại MainActivity nhé

Phía trên hàm onCreate(), chúng ta tạo một enum đơn giản để theo dõi trạng thái của Button:

enum class ButtonState {
  LOGGED_OUT,
  LOGGED_IN
}

Như ở phần 2, chúng ta đã tạo sẵn Interface có tên là serviceListener và tại MainActivity chúng ta sẽ implement nó.

Để implement serviceListener trong MainActivity, ta làm như sau:

class MainActivity : AppCompatActivity(), ServiceListener {

Và bắt buộc phải override các hàm bên dưới

override fun loggedIn() {
}

override fun fileDownloaded(file: File) {
}

override fun cancelled() {
}

override fun handleError(exception: Exception) {
}

Khởi tạo thêm thuộc tính cho GoogleDriveService và trạng thái của Button:

private lateinit var googleDriveService: GoogleDriveService
private var state = ButtonState.LOGGED_OUT

Như mình nói, chúng ta cần thay đổi trạng thái của các button dựa trên trạng thái đăng nhập hoặc đăng xuất.

private fun setButtons() {
  when (state) {
    ButtonState.LOGGED_OUT -> {
      status.text = getString(R.string.status_logged_out)
      start.isEnabled = false
      logout.isEnabled = false
      login.isEnabled = true
    }

    else -> {
      status.text = getString(R.string.status_logged_in)
      start.isEnabled = true
      logout.isEnabled = true
      login.isEnabled = false
    }
  }
}

status, start, logout,  và login là ID của các views bạn đã tạo trong activity_main.xml.

Sau đó update lại hàm onCreate():

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)

  //1
  val config = GoogleDriveConfig(
      getString(R.string.source_google_drive),
      GoogleDriveService.documentMimeTypes
  )
  googleDriveService = GoogleDriveService(this, config)

  //2
  googleDriveService.serviceListener = this

  //3
  googleDriveService.checkLoginStatus()

  //4
  login.setOnClickListener {
    googleDriveService.auth()
  }
  start.setOnClickListener {
    googleDriveService.pickFiles(null)
  }
  logout.setOnClickListener {
    googleDriveService.logout()
    state = ButtonState.LOGGED_OUT
    setButtons()
  }

  //5
  setButtons()
}

Đây là những điều phía trên làm:

#4.  Xử lý tệp nhận từ Google Drive

Thêm hàm onActivityResult()và kết quả như sau:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
 googleDriveService.onActivityResult(requestCode, resultCode, data)
}

Sau đó thì xử lý logic cho các hàm mà chúng ta override từ serviceListener

override fun loggedIn() {
  state = ButtonState.LOGGED_IN
  setButtons()
}

override fun fileDownloaded(file: File) {
  val intent = Intent(Intent.ACTION_VIEW)
  val apkURI = FileProvider.getUriForFile(
      this,
      applicationContext.packageName + ".provider",
      file)
  val uri = Uri.fromFile(file)
  val extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
  val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
  intent.setDataAndType(apkURI, mimeType)
  intent.flags = FLAG_GRANT_READ_URI_PERMISSION
  if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
  } else {
    Snackbar.make(main_layout, R.string.not_open_file, Snackbar.LENGTH_LONG).show()
  }
}

override fun cancelled() {
  Snackbar.make(main_layout, R.string.status_user_cancelled, Snackbar.LENGTH_LONG).show()
  }

override fun handleError(exception: Exception) {
  val errorMessage = getString(R.string.status_error, exception.message)
  Snackbar.make(main_layout, errorMessage, Snackbar.LENGTH_LONG).show()
}

Logic bên trong các hàm loggedIn(), cancelled(), và handleError() đơn giản là chúng ta cập nhập giao diện khi sự kiện đó xảy ra thôi.

Trong fileDownloaded() – bạn nhận được một tệp từ Google drive để hệ thống có thể mở tệp đó ra.

Ở đây, có một chỗ mình lưu ý với các bạn đó là: FileProvider.getUriForFile(). Từ Android 8.0 Oreo trở lên, bạn không thể sử dụng file://. Thay vào đó phải sử dụng content://, vì vậy bạn cần cung cấp FileProvider của riêng bạn để mở chúng.

OK, về cơ bản là đã xong rồi đấy. Chạy thử ứng dụng thôi.

Đầu tiên là yêu cầu đăng nhập

Tích hợp Google Drive SDK vào ứng dụng Android

Trình chọn tài khoản hiện ra. Sau khi đã chọn một tài khoản, bạn sẽ cần cấp quyền truy cập Google Drive của mình.

Tiếp theo, nhấn nút “Bắt đầu Google Drive” và bạn sẽ thấy các tệp của mình như sau:

Tích hợp Google Drive vào ứng dụng

Khi bạn chọn một tệp và nhấn Select, quá trình tải xuống sẽ bắt đầu. Khi tải xong, bạn sẽ thấy tệp đó xuất hiện trong trình quản lý file của hệ thống.

Quá tuyệt phải không?

Tổng kết

Sau rất nhiều cố gắng, cuối cùng mình đã hoàn thành bài hướng dẫn tích hợp Google Drive vào ứng dụng Android. Để các bạn có thể hiểu bản chất và biết cách thực hiện nên mình đã cố gắng viết chi tiết hết mức. Hi vọng các bạn sẽ thích cách viết này

Toàn bộ source code của bài hướng dẫn này, các bạn download tại đây nhé

Nếu bạn có bất kì ý tưởng hay thắc mắc thì đừng ngần ngại để lại comment bên dưới nhé. Mình luôn luôn chào đón

 

Xem tiếp các bài trong Series
Phần trước: Tích hợp Google Drive SDK vào ứng dụng Android từ A-Z – Phần 2

Bình luận. Đặt câu hỏi cũng là một cách học

avatar
  Theo dõi bình luận  
Thông báo