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
.
Danh mục | Tên | Nội dung 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. | |
Policy | Policy | 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 | Phương thức 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 một ứ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ừ phi ứ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 một 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. |
Phản hồi của máy chủ
Bảng 2 liệt kê tất cả các trường phản hồi giấy phép do máy chủ cấp phép trả về.
Trường | Nội dung mô tả |
---|---|
responseCode |
Mã phản hồi do máy chủ cấp phép trả về. Mã phản hồi được nêu trong phần Mã phản hồi của máy chủ. |
signedData |
Một chuỗi nối chứa dữ liệu do máy chủ cấp phép trả về như sau: responseCode|nonce|packageName|versionCode|userId|timestamp:extras .
|
signature |
Chữ ký của signedData bằng một khoá dành riêng cho ứng dụng.
|
Mã phản hồi của máy chủ
Bảng 3 liệt kê tất cả cá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ả cá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ả các biện pháp xử lý cần thiết đối với các mã phản hồi này.
Mã phản hồi | Biểu diễn giá trị số nguyên | Nội dung mô tả | Đã ký? | Thông tin bổ sung | Bình luận |
---|---|---|---|---|---|
LICENSED |
0 |
Ứ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. | Có | VT , GT , GR |
Cho phép truy cập theo các điều kiện ràng buộc của Policy . |
LICENSED_OLD_KEY |
2 |
Ứ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. | 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 |
1 |
Ứ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 |
257 |
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 trong Policy . |
|
ERROR_SERVER_FAILURE |
4 |
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 trong Policy .
|
|
ERROR_INVALID_PACKAGE_NAME |
258 |
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 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 |
259 |
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 |
3 |
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 xuất bản ứng dụng 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ợ.
Thông tin 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 các chế độ cài đặt dưới dạng các cặp khoá – giá trị trong trường "bổ sung" của phản hồi cấp phép.
Mọi quy trình triển khai Policy
đều có thể trích xuất các chế độ cài đặt bổ sung từ phản hồi cấp phép và sử dụng các chế độ đó 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 chế độ cài đặt.
Thông tin bổ sung | Nội dung mô tả |
---|---|
VT |
Dấu thời gian về thời hạn 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ề thông tin bổ sung này cho các phản hồi |
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. Đâ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 phản hồi tất cả các yêu cầu 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 thông tin 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ằngPolicy
đã 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 processServerResponse()
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á GT
và GR
.
Ứng dụng Policy
có thể trích xuất các khoá bổ sung GT
và GR
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ồiRETRY
vào bộ nhớ đệm và tăng số lượng phản hồiRETRY
. 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ị GT
và GR
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; }