Phát triển cho các mạng vệ tinh bị hạn chế

Mạng vệ tinh sẽ có lúc đủ mạnh để hoạt động như mạng bình thường và hoạt động liền mạch với mọi trường hợp sử dụng ứng dụng; nhưng hiện tại, dữ liệu trên các mạng này là một nguồn tài nguyên khan hiếm. Mạng dựa trên vệ tinh có các hạn chế về việc sử dụng dữ liệu được gọi là mạng vệ tinh bị hạn chế.

Do những hạn chế này, các ứng dụng Android không sử dụng các mạng này theo mặc định. Nếu muốn ứng dụng hoạt động trên các mạng vệ tinh bị hạn chế, bạn phải xác định ứng dụng của mình là được tối ưu hoá để sử dụng dữ liệu vệ tinhđiều chỉnh các trường hợp sử dụng của ứng dụng để tiết kiệm tài nguyên khi kết nối với mạng vệ tinh bị hạn chế.

Điều chỉnh các trường hợp sử dụng của ứng dụng

Tất cả những gì bạn phải làm để cho phép ứng dụng của mình truy cập vào các mạng vệ tinh bị hạn chế là chọn sử dụng, nhưng bạn có thể cần thực hiện thêm các thay đổi để tối ưu hoá hành vi của ứng dụng nhằm sử dụng tài nguyên mạng bị hạn chế một cách có trách nhiệm. Sau đây là một số điều cần cân nhắc khi bạn tối ưu hoá để sử dụng dữ liệu có hạn:

  • Quyết định xem ứng dụng của bạn có phù hợp để sử dụng trên các mạng bị hạn chế hay không. Trong mọi trường hợp, một số ứng dụng không phù hợp với các mạng bị hạn chế dữ liệu. Ví dụ: các ứng dụng phát trực tuyến video có thể chọn không sử dụng mạng vệ tinh, mặc dù vẫn có thể xác định sự hiện diện của mạng vệ tinh và thông báo cho người dùng rằng các ứng dụng này sẽ không hoạt động trên mạng bị hạn chế hiện có.
  • Xác định các trường hợp sử dụng cụ thể để hạn chế hoặc sửa đổi. Một số tính năng của ứng dụng có thể phù hợp hơn với các điều kiện dữ liệu bị hạn chế so với những tính năng khác. Ví dụ: việc gửi tin nhắn văn bản sẽ hoạt động tốt, nhưng việc cố gắng tải video HD lên có thể sẽ khiến người dùng có trải nghiệm không tốt. Điều này tương tự như cách nhiều ứng dụng thay đổi hành vi khi chuyển vùng.
  • Điều chỉnh cách ứng dụng của bạn sử dụng tài nguyên mạng. Mạng bị hạn chế hoạt động hiệu quả nhất khi các ứng dụng thực hiện các thao tác mạng theo đợt và dành phần lớn thời gian không sử dụng mạng. Tránh tạo lưu lượng truy cập mạng liên tục hoặc quá nhiều. Ví dụ: âm thanh nhấn để nói phù hợp hơn nhiều với các điều kiện mạng bị hạn chế so với cuộc gọi âm thanh theo thời gian thực.

Bạn cũng cần thực hiện một số thay đổi cụ thể nếu ứng dụng của bạn sử dụng logic mạng phức tạp hoặc Giải pháp gửi thông báo qua đám mây của Firebase.

Tự xác định là được tối ưu hoá cho mạng bị hạn chế

Để xác định ứng dụng của bạn là ứng dụng được tối ưu hoá cho mạng bị hạn chế và chọn sử dụng các mạng đó, hãy cập nhật tệp kê khai ứng dụng bằng một phần tử <meta-data> như sau:

<meta-data android:name="android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED"
          android:value="PACKAGE_NAME" />

Phần tử này cho phép ứng dụng của bạn sử dụng mạng vệ tinh bị hạn chế khi đó là mạng duy nhất có sẵn. Thẻ này cũng thông báo cho hệ thống rằng ứng dụng của bạn được tối ưu hoá cho các mạng bị hạn chế, hỗ trợ người dùng khám phá bằng cách liệt kê ứng dụng đó trong số các ứng dụng có hỗ trợ vệ tinh trong ứng dụng cài đặt.

Thay đổi hành vi trong điều kiện dữ liệu bị hạn chế

Nếu cần thay đổi hành vi của ứng dụng khi sử dụng mạng bị hạn chế hoặc nếu ứng dụng của bạn có logic từ trước sử dụng ConnectivityManager để quản lý việc sử dụng mạng, thì bạn cần thực hiện một số thay đổi đối với luồng mạng.

Phát hiện các điều kiện dữ liệu bị hạn chế

Đối tượng NetworkCapabilities dùng cho các yêu cầu mạng bao gồm một bit NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED được đặt theo mặc định trên tất cả các mạng và bị xoá trên những mạng bị hạn chế về băng thông. Bạn có thể xác định xem một mạng có bị hạn chế băng thông hay không bằng cách kiểm tra xem mạng đó có khả năng NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED hay không.

Làm việc với các mạng bị hạn chế

Các đối tượng NetworkRequest cũng bao gồm chức năng NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED theo mặc định. Xoá chức năng này để cho biết rằng các mạng bị hạn chế là chấp nhận được.

Khi phát hiện thấy mình đã kết nối với một mạng bị hạn chế, bạn có thể điều chỉnh các tính năng của ứng dụng nếu cần:

Kotlin

val HandlerThread = HandlerThread("SatelliteNetworkMonitor"
handlerThread.start()
val handler = Handler(handlerThread.getLooper())

// Make the network request.
val request = NetworkRequest.Builder()
    .addCapability(NET_CAPABILITY_INTERNET
    .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
    .build()

// Register for the callback.
val callback = NetworkCallback() {
    override fun onCapabilitiesChanged(net: Network, nc: NetWorkCapabilities) {
        updateAppUseCases(net, nc)
    }

    fun updateAppUseCases(net: Network, nc: NetworkCapabilities) {
        if (!nc.hasCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) ||
             nc.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {
            // Adapt to constrained network or disable heavy data usage features.
            ...
        } else {
            // Revert to unconstrained behavior.
            ...
        }
    }
}
// Where cm is your ConnectivityManager object:
cm.registerBestMatchingNetworkCallback(request, callback, handler)

Java

HandlerThread handlerThread = new HandlerThread("SatelliteNetworkMonitor");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());

// Make the network request.
NetworkRequest request = new NetworkRequest.Builder()
    .addCapability(NET_CAPABILITY_INTERNET)
    .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
    .build();

// Register for the callback.
NetworkCallback callback = new NetworkCallback() {
    @Override
    public void onCapabilitiesChanged(Network net, NetworkCapabilities nc) {
        updateAppUsecases(net, nc);
    }
    private void updateAppUsecases(Network net, NetworkCapabilities nc) {
        if (!nc.hasCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) || nc.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {
            // Adapt to constrained network or disable heavy data usage features.
            ...
        } else {
            // Revert to unconstrained behavior.
            ...
        }
    }
};
// Where cm is your ConnectivityManager object:
cm.registerBestMatchingNetworkCallback(request, callback, handler);

Nhận thông báo FCM trên các mạng bị hạn chế

Nếu ứng dụng của bạn sử dụng Giải pháp gửi thông báo qua đám mây của Firebase (FCM) để nhận thông báo từ máy chủ ứng dụng, thì bạn có thể cho biết rằng một thông báo cụ thể sẽ được gửi ngay cả trên các mạng bị hạn chế bằng cách thêm cờ bandwidth_constrained_ok khi truyền thông báo đến máy chủ FCM:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    }
    "android": {
       "bandwidth_constrained_ok": true
    }
  }
}

Nếu một thông báo không có cờ này, thì máy chủ FCM chỉ gửi thông báo đó khi thiết bị được kết nối thông qua một mạng không bị hạn chế.