Lưu ý: Để cấp phép trong các ứng dụng và trò chơi trực tuyến, bạn nên dùng API Tính toàn vẹn của Play. Tìm hiểu thêm.

Tài liệu tham khảo về hoạt động cấp phép

Lớp và giao diện LVL

Bảng 1 liệt kê tất cả tệp nguồn trong Thư viện xác minh giấy phép (LVL) có sẵn thông qua SDK Android. Tất cả tệp đều nằm trong gói com.android.vending.licensing.

Bảng 1. Tóm tắt các lớp và giao diện của thư viện LVL.

Danh mục Tên Mô tả
Kiểm tra giấy phép và kết quả LicenseChecker Lớp mà bạn tạo bản sao (hoặc lớp con) để bắt đầu một quy trình kiểm tra giấy phép.
LicenseCheckerCallback Giao diện bạn triển khai để xử lý kết quả của hoạt động kiểm tra giấy phép.
Chính sách Chính sách Giao diện mà bạn triển khai để xác định xem có cấp quyền truy cập vào ứng dụng hay không, dựa trên phản hồi của giấy phép.
ServerManagedPolicy Triển khai Policy mặc định. Sử dụng các tuỳ chọn cài đặt do máy chủ cấp phép cung cấp để quản lý bộ nhớ cục bộ của dữ liệu giấy phép, tính hợp lệ của giấy phép, thử lại.
StrictPolicy Phương thức triển khai Policy thay thế. Chỉ thực thi việc cấp phép dựa trên phản hồi giấy phép trực tiếp từ máy chủ. Không yêu cầu thử lại hoặc lưu vào bộ nhớ đệm.
Làm rối dữ liệu
(không bắt buộc)
Trình làm rối Giao diện mà bạn triển khai nếu bạn đang sử dụng Policy (chẳng hạn như ServerManagedPolicy) sẽ lưu dữ liệu phản hồi giấy phép vào bộ nhớ đệm trong một bộ nhớ liên tục. Áp dụng thuật toán làm rối để mã hoá và giải mã dữ liệu đang được ghi hoặc đọc.
AESObfuscator Việc triển khai Trình làm rối mặc định bằng cách sử dụng thuật toán mã hoá/giải mã AES để làm rối/gỡ rối dữ liệu.
Giới hạn thiết bị
(không bắt buộc)
DeviceLimiter Giao diện bạn triển khai nếu muốn hạn chế việc sử dụng ứng dụng cho một thiết bị cụ thể. Được gọi từ LicenseValidator. Việc triển khai DeviceLimiter không được khuyến nghị cho hầu hết ứng dụng vì phương thức này cần một máy chủ phụ trợ và có thể khiến người dùng mất quyền truy cập vào các ứng dụng được cấp phép, trừ khi ứng dụng được thiết kế cẩn thận.
NullDeviceLimiter Cách triển khai DeviceLimiter mặc định là không hoạt động (cho phép truy cập vào tất cả thiết bị).
Cốt lõi thư viện, không cần tích hợp ResponseData Lớp chứa các trường của phản hồi giấy phép.
LicenseValidator Lớp giải mã và xác minh một phản hồi đã nhận được từ máy chủ cấp phép.
ValidationException Lớp cho biết các lỗi xảy ra khi xác thực tính toàn vẹn của dữ liệu được Trình làm rối quản lý.
PreferenceObfuscator Lớp tiện ích giúp ghi/đọc dữ liệu đã được làm rối vào bộ nhớ SharedPreferences của hệ thống.
ILicensingService Giao diện IPC một chiều mà yêu cầu kiểm tra giấy phép được truyền tới ứng dụng Google Play.
ILicenseResultListener Triển khai lệnh gọi lại IPC một chiều, trong đó ứng dụng nhận được phản hồi không đồng bộ từ máy chủ cấp phép.

Mã phản hồi của máy chủ

Bảng 2 liệt kê tất cả mã phản hồi giấy phép mà máy chủ cấp phép hỗ trợ. Nhìn chung, ứng dụng phải xử lý được tất cả mã phản hồi này. Theo mặc định, lớp LicenseValidator trong LVL cung cấp cho bạn tất cả biện pháp xử lý cần thiết cho các mã phản hồi này.

Bảng 2. Bản tóm tắt mã phản hồi được máy chủ Google Play trả về trong một phản hồi giấy phép.

Mã phản hồi Mô tả Đã ký? Khoá bổ sung Bình luận
LICENSED Ứng dụng được cấp phép cho người dùng. Người dùng đã mua ứng dụng hoặc được uỷ quyền tải xuống và cài đặt phiên bản alpha hoặc phiên bản thử nghiệm của ứng dụng. VTGT, GR Cho phép truy cập theo các điều kiện ràng buộc của Policy.
LICENSED_OLD_KEY Ứng dụng được cấp phép cho người dùng, tuy nhiên còn có một phiên bản của ứng dụng được cập nhật và ký bằng một khoá khác. VT, GT, GR, UT Không bắt buộc phải cho phép truy cập theo các điều kiện ràng buộc trong Policy.

Có thể cho biết cặp khoá được sử dụng bởi phiên bản ứng dụng đã cài đặt là không hợp lệ hoặc bị xâm phạm. Ứng dụng có thể cho phép truy cập nếu cần, hoặc thông báo cho người dùng rằng có thể nâng cấp và hạn chế sử dụng thêm cho đến khi nâng cấp.

NOT_LICENSED Ứng dụng không được cấp phép cho người dùng. Không Không cho phép truy cập.
ERROR_CONTACTING_SERVER Lỗi cục bộ – ứng dụng Google Play không thể kết nối với máy chủ cấp phép, có thể do sự cố về tình trạng sẵn có của kết nối mạng. Không Thử lại việc kiểm tra giấy phép theo giới hạn các lần thử lại Policy.
ERROR_SERVER_FAILURE Lỗi máy chủ – máy chủ không thể tải cặp khoá của ứng dụng để cấp phép. Không Thử lại việc kiểm tra giấy phép theo giới hạn các lần thử lại Policy.
ERROR_INVALID_PACKAGE_NAME Lỗi cục bộ — ứng dụng đã yêu cầu thực hiện kiểm tra giấy phép cho một gói hàng chưa được cài đặt trên thiết bị. Không Không thử kiểm tra lại giấy phép.

Thường xảy ra do một lỗi phát triển.

ERROR_NON_MATCHING_UID Lỗi cục bộ – ứng dụng đã yêu cầu thực hiện kiểm tra giấy phép cho một gói có UID (gói, cặp mã nhận dạng người dùng) không khớp với UID của gói ứng dụng đang yêu cầu. Không Không thử kiểm tra lại giấy phép.

Thường xảy ra do một lỗi phát triển.

ERROR_NOT_MARKET_MANAGED Lỗi máy chủ – Google Play không nhận dạng được ứng dụng (tên gói). Không Không thử kiểm tra lại giấy phép.

Có thể cho biết rằng ứng dụng chưa được phát hành qua Google Play, hoặc đã xảy ra lỗi phát triển trong quá trình triển khai cấp phép.

Lưu ý: Như đã nêu trong tài liệu Thiết lập môi trường kiểm thử, bạn có thể ghi đè mã phản hồi theo cách thủ công cho nhà phát triển ứng dụng và mọi người dùng đăng ký kiểm thử qua Google Play Console.

Lưu ý: Trước đây, bạn có thể kiểm thử ứng dụng bằng cách tải phiên bản "nháp" chưa phát hành lên. Chức năng này không còn được hỗ trợ; thay vào đó, bạn phải phát hành APK này lên kênh phân phối alpha hoặc beta. Để biết thêm thông tin, hãy xem phần Ứng dụng chưa chính thức không còn được hỗ trợ.

Khoá bổ sung trong phản hồi của máy chủ

Để giúp ứng dụng quản lý quyền truy cập vào ứng dụng trong khoảng thời gian hoàn tiền của ứng dụng, đồng thời cung cấp các thông tin khác, Máy chủ cấp phép sẽ bao gồm một số thông tin trong nội dung phản hồi giấy phép. Cụ thể, dịch vụ cung cấp các giá trị được đề xuất trong thời hạn hiệu lực của giấy phép ứng dụng, thời gian gia hạn thử lại, số lần thử lại tối đa được cho phép và các tuỳ chọn cài đặt khác. Nếu ứng dụng sử dụng tệp mở rộng APK, phản hồi cũng sẽ bao gồm tên, kích thước và URL của tệp. Máy chủ sẽ thêm tuỳ chọn cài đặt dưới dạng các cặp khoá – giá trị trong trường "khoá bổ sung" của phản hồi giấy phép.

Mọi hoạt động triển khai Policy đều có thể trích xuất các tuỳ chọn cài đặt khoá bổ sung từ phản hồi giấy phép và sử dụng chúng nếu cần. Việc triển khai Policy mặc định của LVL, ServerManagedPolicy, đóng vai trò là phương thức triển khai công việc và minh hoạ cách thu thập, lưu trữ và sử dụng các tuỳ chọn cài đặt.

Bảng 3. Thông tin tóm tắt về các tuỳ chọn cài đặt quản lý giấy phép được máy chủ Google Play cung cấp trong một phản hồi giấy phép.

Khoá bổ sungMô tả
VT Dấu thời gian có hiệu lực của giấy phép. Chỉ định ngày/giờ mà phản hồi giấy phép hiện tại (được lưu vào bộ nhớ đệm) hết hạn và phải được kiểm tra lại trên máy chủ cấp phép. Xem mục dưới đây về Thời hạn có hiệu lực của giấy phép.
GT Dấu thời gian của thời gian gia hạn. Chỉ định thời điểm kết thúc khoảng thời gian mà Chính sách có thể cho phép truy cập vào ứng dụng, ngay cả khi trạng thái phản hồi là RETRY.

Giá trị này do máy chủ quản lý. Tuy nhiên, giá trị thông thường sẽ là từ 5 ngày trở lên. Hãy xem mục bên dưới về Thời gian thử lại và số lần thử lại tối đa.

GR Số lần thử lại tối đa. Chỉ định số lần kiểm tra giấy phép RETRY liên tiếp mà Policy cho phép, trước khi từ chối quyền truy cập của người dùng vào ứng dụng này.

Giá trị này do máy chủ quản lý. Tuy nhiên, giá trị thông thường sẽ là "10" trở lên. Hãy xem mục bên dưới về Thời gian thử lại và số lần thử lại tối đa.

UT Dấu thời gian cập nhật. Chỉ định ngày/giờ mà bản cập nhật ứng dụng gần nhất được tải lên và phát hành.

Máy chủ chỉ trả về khoá bổ sung này cho các phản hồi LICENSED_OLD_KEYS để cho phép Policy xác định thời gian đã trôi qua kể từ khi bản cập nhật được phát hành với khoá cấp phép mới trước khi từ chối quyền truy cập của người dùng vào ứng dụng.

FILE_URL1 hoặc FILE_URL2 URL của tệp mở rộng (1 dành cho tệp chính, 2 là tệp bản vá). Hãy sử dụng cách này để tải tệp xuống qua HTTP.
FILE_NAME1 hoặc FILE_NAME2 Tên của tệp mở rộng (1 là dành cho tệp chính, 2 là tệp bản vá). Bạn phải sử dụng tên này khi lưu tệp trên thiết bị.
FILE_SIZE1 hoặc FILE_SIZE2 Kích thước của tệp tính bằng byte (1 là dành cho tệp chính, 2 là tệp bản vá). Sử dụng URL này để hỗ trợ việc tải xuống và đảm bảo có đủ dung lượng trên vị trí bộ nhớ dùng chung của thiết bị trước khi tải xuống.

Thời hạn giấy phép có hiệu lực

Máy chủ cấp phép của Google Play sẽ thiết lập khoảng thời gian giấy phép có hiệu lực cho tất cả ứng dụng đã tải xuống. Khoảng thời gian này là khoảng thời gian mà trạng thái giấy phép của ứng dụng phải được coi là không thay đổi và có thể lưu vào bộ nhớ đệm thông qua một Policy cấp phép trong ứng dụng. Máy chủ cấp phép bao gồm thông tin về khoảng thời gian có hiệu lực khi cung cấp phản hồi tới tất cả quy trình kiểm tra giấy phép, đồng thời thêm một dấu thời gian về thời điểm hết hiệu lực vào phản hồi dưới dạng khoá bổ sung trong khoá VT. Policy có thể trích xuất giá trị khoá VT và sử dụng để cho phép truy cập vào ứng dụng theo cách có điều kiện mà không cần kiểm tra lại giấy phép cho đến khi hết thời hạn hiệu lực.

Tính hợp lệ của giấy phép thông báo cho Policy cấp phép khi nào phải kiểm tra lại trạng thái cấp phép với máy chủ cấp phép. Ứng dụng này không nhằm mục đích cho biết một ứng dụng có thực sự được cấp phép để sử dụng hay không. Nghĩa là khi thời hạn hiệu lực của giấy phép ứng dụng hết hạn không có nghĩa là ứng dụng không còn được cấp phép để sử dụng nữa. Thay vào đó, điều này chỉ cho biết rằng Policy phải kiểm tra lại trạng thái cấp phép với máy chủ. Theo đó, miễn là thời hạn hiệu lực của giấy phép chưa hết, Policy có thể lưu trạng thái giấy phép ban đầu vào bộ nhớ đệm trên máy tính và trả lại trạng thái giấy phép đã lưu vào bộ nhớ đệm thay vì gửi yêu cầu kiểm tra giấy phép mới tới máy chủ.

Máy chủ cấp phép quản lý thời gian có hiệu lực để giúp ứng dụng thực thi cấp phép trong suốt thời gian hoàn tiền mà Google Play cung cấp cho ứng dụng trả phí. Máy chủ cấp phép này thiết lập thời hạn có hiệu lực dựa trên việc ứng dụng có được mua hay không và nếu có thì cách đây bao lâu. Cụ thể, máy chủ sẽ thiết lập một khoảng thời gian hợp lệ như sau:

  • Đối với một ứng dụng trả phí, máy chủ sẽ thiết lập thời hạn có hiệu lực của giấy phép ban đầu để phản hồi giấy phép vẫn có hiệu lực, miễn là ứng dụng vẫn trong giai đoạn có thể được hoàn tiền. Một Policy cấp phép trong ứng dụng có thể lưu lại kết quả trong bộ nhớ đệm của quy trình kiểm tra giấy phép ban đầu và không cần kiểm tra lại giấy phép cho đến khi hết thời hạn có hiệu lực.
  • Khi một ứng dụng hết thời gian được hoàn tiền, máy chủ sẽ thiết lập khoảng thời gian có hiệu lực dài hơn – thường là một vài ngày.
  • Đối với một ứng dụng miễn phí, máy chủ sẽ thiết lập thời gian có hiệu lực là một giá trị rất cao (long.MAX_VALUE). Thao tác này đảm bảo rằng Policy đã lưu cục bộ vào bộ nhớ đệm dấu thời gian hợp lệ, bạn không cần kiểm tra lại trạng thái giấy phép của ứng dụng trong tương lai.

Việc triển khai ServerManagedPolicy sử dụng dấu thời gian được trích xuất (mValidityTimestamp) làm điều kiện chính để xác định liệu có cần kiểm tra lại trạng thái giấy phép với máy chủ trước khi cho phép người dùng truy cập vào ứng dụng hay không.

Khoảng thời gian thử lại và số lần thử lại tối đa

Trong một số trường hợp, điều kiện mạng hoặc hệ thống có thể ngăn cản quá trình kiểm tra giấy phép của ứng dụng đến máy chủ cấp phép hoặc ngăn phản hồi của máy chủ về ứng dụng Google Play. Ví dụ: người dùng có thể khởi chạy ứng dụng khi không có mạng di động hoặc kết nối dữ liệu nào, chẳng hạn như khi trên máy bay hoặc khi kết nối mạng không ổn định hoặc tín hiệu mạng di động yếu.

Khi sự cố mạng ngăn chặn hoặc làm gián đoạn quá trình kiểm tra giấy phép, ứng dụng Google Play sẽ thông báo cho ứng dụng bằng cách trả về một mã phản hồi RETRY cho phương thức processServerResponse() của Policy. Trong trường hợp hệ thống gặp sự cố, chẳng hạn như khi ứng dụng không thể liên kết với phương pháp triển khai ILicensingService của Google Play, bản thân thư viện LicenseChecker sẽ gọi phương thức Chính sách processServerResonse() với một mã phản hồi RETRY.

Nhìn chung, mã phản hồi RETRY là tín hiệu để ứng dụng biết rằng đã xảy ra lỗi khiến quá trình kiểm tra giấy phép không hoàn tất.

Máy chủ Google Play giúp một ứng dụng quản lý việc cấp phép trong các điều kiện lỗi bằng cách đặt lại "thời gian gia hạn" và số lần thử lại tối đa được đề xuất. Máy chủ bao gồm các giá trị này trong tất cả phản hồi kiểm tra giấy phép, thêm các giá trị đó dưới dạng khoá bổ sung trong khoá GTGR.

Ứng dụng Policy có thể trích xuất các khoá bổ sung GTGR rồi sử dụng chúng để cho phép truy cập vào ứng dụng theo cách có điều kiện như sau:

  • Đối với việc kiểm tra giấy phép dẫn đến một phản hồi RETRY, Policy sẽ lưu mã phản hồi RETRY vào bộ nhớ đệm và tăng số lượng phản hồi RETRY.
  • Policy sẽ cho phép người dùng truy cập vào ứng dụng, với điều kiện thời gian gia hạn thử lại vẫn còn hoặc chưa đạt đến số lần thử lại tối đa.

ServerManagedPolicy sử dụng các giá trị GTGR do máy chủ cung cấp như mô tả bên trên. Ví dụ bên dưới cho thấy cách xử lý có điều kiện các phản hồi thử lại trong phương thức allow(). Số lượng phản hồi RETRY được duy trì trong phương thức processServerResponse() không được hiển thị.

Kotlin

fun allowAccess(): Boolean {
    val ts = System.currentTimeMillis()
    return when(lastResponse) {
        LICENSED -> {
            // Check if the LICENSED response occurred within the validity timeout.
            ts <= validityTimestamp  // Cached LICENSED response is still valid.
        }
        RETRY -> {
            ts < lastResponseTime + MILLIS_PER_MINUTE &&
                    // Only allow access if we are within the retry period
                    // or we haven't used up our max retries.
                    (ts <= retryUntil || retryCount <= maxRetries)
        }
        else -> false
    }
}

Java

public boolean allowAccess() {
    long ts = System.currentTimeMillis();
    if (lastResponse == LicenseResponse.LICENSED) {
        // Check if the LICENSED response occurred within the validity timeout.
        if (ts <= validityTimestamp) {
            // Cached LICENSED response is still valid.
            return true;
        }
    } else if (lastResponse == LicenseResponse.RETRY &&
                ts < lastResponseTime + MILLIS_PER_MINUTE) {
        // Only allow access if we are within the retry period
        // or we haven't used up our max retries.
        return (ts <= retryUntil || retryCount <= maxRetries);
    }
    return false;
}