Đọc trạng thái mạng

Android cho phép ứng dụng tìm hiểu các thay đổi động về khả năng kết nối. Sử dụng các lớp sau để theo dõi và ứng phó trước thay đổi về khả năng kết nối:

  • ConnectivityManager cho ứng dụng biết về trạng thái kết nối trong hệ thống.
  • Lớp Network biểu thị một trong các mạng mà thiết bị đã kết nối. Bạn có thể dùng đối tượng Network làm khoá để thu thập thông tin về mạng bằng ConnectivityManager hoặc để liên kết các cổng trên mạng. Khi mạng ngắt kết nối, đối tượng Network sẽ không còn sử dụng được nữa. Ngay cả khi thiết bị được kết nối lại sau đó với cùng một thiết bị, một đối tượng Network mới vẫn biểu thị mạng mới.
  • Đối tượng LinkProperties chứa thông tin về đường liên kết của một mạng, chẳng hạn như danh sách máy chủ DNS, địa chỉ IP cục bộ và các tuyến mạng được cài đặt cho mạng.
  • Đối tượng NetworkCapabilities chứa thông tin về các thuộc tính của mạng, chẳng hạn như mạng truyền tải (Wi-Fi, mạng di động, Bluetooth) và khả năng của mạng. Ví dụ: bạn có thể truy vấn đối tượng để xác định xem mạng có thể gửi MMS không, có đang ở sau trang xác thực không hoặc có được đo lượng dữ liệu không.

Các ứng dụng quan tâm đến trạng thái kết nối tức thì vào một thời điểm bất kỳ có thể gọi phương thức ConnectivityManager để tìm hiểu loại mạng hiện có là gì. Các phương thức này rất hữu ích trong việc gỡ lỗi và thỉnh thoảng xem xét thông tin tổng quan nhanh về khả năng kết nối vào bất cứ lúc nào.

Tuy nhiên, các phương thức ConnectivityManager đồng bộ không cho ứng dụng của bạn biết về điều gì đang xảy ra sau một lần gọi, vì vậy, các phương thức này không cho phép bạn cập nhật giao diện người dùng. Các phương thức này cũng không thể điều chỉnh hành vi của ứng dụng khi mạng bị ngắt kết nối hoặc khi tính năng của mạng thay đổi.

Khả năng kết nối có thể thay đổi bất cứ lúc nào, và hầu hết ứng dụng đều cần có khung hiển thị luôn mới và cập nhật về trạng thái mạng trên thiết bị. Các ứng dụng có thể đăng ký một lệnh gọi lại bằng ConnectivityManager để nhận cảnh báo về những thay đổi mà ứng dụng quan tâm. Khi sử dụng lệnh gọi lại, ứng dụng của bạn có thể phản ứng ngay lập tức với mọi thay đổi liên quan đến khả năng kết nối mà không phải dùng đến các cuộc thăm dò tốn kém khiến bỏ lỡ các bản cập nhật nhanh.

Việc sử dụng NetworkCallback và những cách khác để tìm hiểu về trạng thái kết nối của thiết bị không yêu cầu quyền cụ thể nào. Tuy nhiên, một số mạng phải tuân theo các quyền cụ thể. Ví dụ: ứng dụng có thể không dùng được một số mạng bị hạn chế. Để liên kết với một mạng ở chế độ nền, bạn cần có quyền CHANGE_NETWORK_STATE. Một số lệnh gọi có thể cần các quyền cụ thể để chạy. Hãy tham khảo tài liệu cụ thể cho từng lệnh gọi để biết thông tin chi tiết.

Lấy trạng thái tức thời

Thiết bị chạy Android có thể duy trì nhiều kết nối cùng một lúc. Để lấy thông tin về trạng thái mạng hiện tại, trước tiên, hãy nhận thực thể của ConnectivityManager:

Kotlin

val connectivityManager = getSystemService(ConnectivityManager::class.java)

Java

ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);

Tiếp theo, hãy sử dụng thực thể này để tham chiếu đến mạng mặc định hiện tại cho ứng dụng của bạn:

Kotlin

val currentNetwork = connectivityManager.getActiveNetwork()

Java

Network currentNetwork = connectivityManager.getActiveNetwork();

Với thông tin tham chiếu đến một mạng, ứng dụng của bạn có thể yêu cầu thông tin về mạng đó.

Kotlin

val caps = connectivityManager.getNetworkCapabilities(currentNetwork)
val linkProperties = connectivityManager.getLinkProperties(currentNetwork)

Java

NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(currentNetwork);
LinkProperties linkProperties = connectivityManager.getLinkProperties(currentNetwork);

Để có được chức năng hữu ích hơn, hãy đăng ký NetworkCallback. Để biết thêm thông tin về cách đăng ký lệnh gọi lại mạng, hãy xem phần Theo dõi sự kiện mạng.

NetworkCapabilities và LinkProperties

Đối tượng NetworkCapabilitiesLinkProperties cung cấp thông tin về tất cả các thuộc tính mà hệ thống biết về một mạng.

Đối tượng LinkProperties biết các tuyến đường, địa chỉ liên kết, tên giao diện, thông tin proxy (nếu có) và máy chủ DNS. Hãy gọi phương thức liên quan trên đối tượng LinkProperties để truy xuất thông tin bạn cần.

Đối tượng NetworkCapabilities đóng gói thông tin về mạng truyền tảitính năng của mạng truyền tải đó.

Mạng truyền tải (transport) là một từ chung chỉ phương tiện vật lý mà trên đó mạng hoạt động. Các ví dụ về mạng truyền tải phổ biến là Ethernet, Wi-Fi và mạng di động. VPN (mạng riêng ảo) và Wi-Fi ngang hàng cũng có thể là mạng truyền tải. Trên Android, một mạng có thể có nhiều mạng truyền tải cùng một lúc. Ví dụ: VPN hoạt động trên cả Wi-Fi và mạng di động. VPN có mạng truyền tải Wi-Fi, mạng di động và VPN. Để tìm hiểu xem liệu một mạng có mạng truyền tải cụ thể hay không, hãy dùng phương thức NetworkCapabilities.hasTransport(int) với một trong các hằng số NetworkCapabilities.TRANSPORT_*.

Một tính năng mô tả thuộc tính của mạng. Các ví dụ về tính năng bao gồm MMS, NOT_METEREDINTERNET. Một mạng có tính năng MMS có thể gửi và nhận tin nhắn của Dịch vụ nhắn tin đa phương tiện, còn một mạng không có tính năng này thì không thể. Một mạng có tính năng NOT_METERED sẽ không tính phí sử dụng dữ liệu cho người dùng. Ứng dụng của bạn có thể kiểm tra xem có tính năng thích hợp hay không bằng phương thức NetworkCapabilities.hasCapability(int) với một trong các hằng số NetworkCapabilities.NET_CAPABILITY_*.

Các hằng số NET_CAPABILITY_* hữu ích nhất bao gồm:

  • NET_CAPABILITY_INTERNET: cho biết mạng đã được thiết lập để truy cập Internet. Đây là tính năng về thiết lập chứ không phải là khả năng thực sự để kết nối với máy chủ công cộng. Ví dụ: một mạng có thể được thiết lập để truy cập Internet nhưng phải qua trang xác thực.

    Mạng di động của nhà mạng thường có tính năng INTERNET, trong khi mạng Wi-Fi P2P cục bộ thường không có tính năng này. Để biết khả năng kết nối thực tế, hãy xem NET_CAPABILITY_VALIDATED.

  • NET_CAPABILITY_NOT_METERED: cho biết mạng không được đo lượng dữ liệu. Mạng được phân loại là có đo lượng dữ liệu khi người dùng nhạy cảm với việc sử dụng nhiều dữ liệu trên kết nối đó do tốn phí, hạn mức dữ liệu hoặc vấn đề về hiệu suất pin.

  • NET_CAPABILITY_NOT_VPN: cho biết mạng không phải là mạng riêng ảo.

  • NET_CAPABILITY_VALIDATED: cho biết mạng cấp quyền truy cập thực tế vào Internet công cộng khi được thăm dò. Một mạng ở sau trang xác thực hoặc một mạng không cung cấp cách phân giải tên miền sẽ không có tính năng này. Đây là thông tin chính xác nhất mà hệ thống có thể cho biết về một mạng thực sự cấp quyền truy cập, mặc dù về nguyên tắc, một mạng được xác thực vẫn có thể bị lọc dựa trên IP hoặc bị mất kết nối đột ngột do các vấn đề như tín hiệu kém.

  • NET_CAPABILITY_CAPTIVE_PORTAL: cho biết mạng có một trang xác thực khi mạng được thăm dò.

Các ứng dụng chuyên biệt hơn có thể sẽ quan tâm đến các tính năng khác. Để biết thêm thông tin, hãy đọc định nghĩa tham số trong NetworkCapabilities.hasCapability(int).

Tính năng của mạng có thể thay đổi bất cứ lúc nào. Khi phát hiện thấy một trang xác thực, hệ thống sẽ hiển thị thông báo mời người dùng đăng nhập. Trong khi điều này đang diễn ra, mạng có tính năng NET_CAPABILITY_INTERNETNET_CAPABILITY_CAPTIVE_PORTAL nhưng không có tính năng NET_CAPABILITY_VALIDATED.

Khi người dùng thực hiện thao tác và đăng nhập vào trang xác thực, thiết bị có thể truy cập vào Internet công cộng, đồng thời mạng sẽ nhận được tính năng NET_CAPABILITY_VALIDATED và bị mất tính năng NET_CAPABILITY_CAPTIVE_PORTAL.

Tương tự như vậy, mạng truyền tải của một mạng có thể thay đổi linh hoạt. Ví dụ: VPN có thể tự định cấu hình lại để sử dụng một mạng nhanh hơn vừa xuất hiện, giống như chuyển từ mạng di động sang Wi-Fi cho mạng cơ bản của VPN. Trong trường hợp này, mạng sẽ mất mạng truyền tải TRANSPORT_CELLULAR, đồng thời nhận mạng truyền tải TRANSPORT_WIFI, trong khi vẫn duy trì mạng truyền tải TRANSPORT_VPN.

Theo dõi sự kiện mạng

Để tìm hiểu về các sự kiện mạng, hãy sử dụng lớp NetworkCallback cùng với ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback)ConnectivityManager.registerNetworkCallback(NetworkCallback) 2 phương thức này phục vụ nhiều mục đích.

Tất cả các ứng dụng Android đều có một mạng mặc định, do hệ thống xác định. Hệ thống thường ưu tiên mạng không đo lượng dữ liệu và mạng nhanh hơn so với mạng có đo lượng dữ liệu và mạng có tốc độ chậm.

Khi ứng dụng đưa ra một yêu cầu mạng, chẳng hạn như với HttpsURLConnection, hệ thống sẽ đáp ứng yêu cầu này bằng cách sử dụng mạng mặc định. Ứng dụng cũng có thể gửi lưu lượng truy cập trên các mạng khác. Để biết thêm thông tin, hãy xem phần các mạng khác.

Mạng được đặt làm mạng mặc định có thể thay đổi bất cứ lúc nào trong suốt thời gian hoạt động của ứng dụng. Một ví dụ điển hình là thiết bị tiến vào phạm vi của một điểm truy cập Wi-Fi đã biết, đang hoạt động, không đo lượng dữ liệu và nhanh hơn mạng di động. Thiết bị sẽ kết nối với điểm truy cập này và chuyển đổi mạng mặc định của tất cả các ứng dụng sang mạng Wi-Fi mới.

Khi một mạng mới trở thành mặc định, mọi kết nối mới mà ứng dụng mở ra sẽ dùng mạng này. Tại một thời điểm sau đó, mọi kết nối còn lại trên mạng mặc định trước đó đều bị buộc kết thúc. Nếu cần phải biết khi nào mạng mặc định thay đổi, thì ứng dụng đó sẽ đăng ký lệnh gọi lại mạng mặc định như sau:

Kotlin

connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network : Network) {
        Log.e(TAG, "The default network is now: " + network)
    }

    override fun onLost(network : Network) {
        Log.e(TAG, "The application no longer has a default network. The last default network was " + network)
    }

    override fun onCapabilitiesChanged(network : Network, networkCapabilities : NetworkCapabilities) {
        Log.e(TAG, "The default network changed capabilities: " + networkCapabilities)
    }

    override fun onLinkPropertiesChanged(network : Network, linkProperties : LinkProperties) {
        Log.e(TAG, "The default network changed link properties: " + linkProperties)
    }
})

Java

connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        Log.e(TAG, "The default network is now: " + network);
    }

    @Override
    public void onLost(Network network) {
        Log.e(TAG, "The application no longer has a default network. The last default network was " + network);
    }

    @Override
    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
        Log.e(TAG, "The default network changed capabilities: " + networkCapabilities);
    }

    @Override
    public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
        Log.e(TAG, "The default network changed link properties: " + linkProperties);
    }
});

Khi một mạng mới trở thành mạng mặc định, ứng dụng sẽ nhận được một lệnh gọi onAvailable(Network) cho mạng mới. Triển khai onCapabilitiesChanged(Network,NetworkCapabilities), onLinkPropertiesChanged(Network,LinkProperties) hoặc cả hai để phản ứng thích hợp với những thay đổi về khả năng kết nối.

Đối với lệnh gọi lại được đăng ký bằng registerDefaultNetworkCallback(), onLost() có nghĩa là mạng đã mất trạng thái là mạng mặc định. Mạng đó có thể đã bị ngắt kết nối.

Mặc dù bạn có thể tìm hiểu về các mạng truyền tải mà mạng mặc định đang sử dụng bằng cách truy vấn NetworkCapabilities.hasTransport(int), nhưng đây là một proxy kém về băng thông hoặc mức đo lượng dữ liệu của mạng. Ứng dụng của bạn không được giả định rằng Wi-Fi luôn không đo lượng dữ liệu và luôn cung cấp băng thông chất lượng hơn so với mạng di động.

Thay vào đó, hãy sử dụng NetworkCapabilities.getLinkDownstreamBandwidthKbps() để đo băng thông và NetworkCapabilites.hasCapability(int) với các đối số NET_CAPABILITY_NOT_METERED để xác định mức đo lượng dữ liệu. Để biết thêm thông tin, hãy xem phần NetworkCapabilities và LinkProperties.

Theo mặc định, phương pháp gọi lại được gọi trên luồng kết nối của ứng dụng. Đây là một luồng riêng biệt được ConnectivityManager sử dụng. Nếu phương thức triển khai các lệnh gọi lại cần thực hiện thêm bất kỳ thao tác nào, hãy gọi các lệnh đó trên một luồng worker riêng bằng cách sử dụng biến thể ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback, Handler).

Huỷ đăng ký lệnh gọi lại khi bạn không sử dụng đến nữa bằng cách gọi ConnectivityManager.unregisterNetworkCallback(NetworkCallback). onPause() của hoạt động chính là nơi phù hợp để thực hiện việc này, đặc biệt nếu bạn đăng ký lệnh gọi lại trong onResume().

Các mạng khác

Mặc dù mạng mặc định là mạng phù hợp duy nhất của hầu hết ứng dụng, nhưng một số ứng dụng có thể chỉ quan tâm đến các mạng có sẵn khác. Để tìm hiểu về những mạng này, ứng dụng sẽ tạo một NetworkRequest phù hợp với nhu cầu của các mạng đó và gọi ConnectivityManager.registerNetworkCallback(NetworkRequest, NetworkCallback).

Quá trình này tương tự như việc theo dõi mạng mặc định. Tuy nhiên, mặc dù có thể chỉ có một mạng mặc định áp dụng cho ứng dụng tại một thời điểm bất kỳ, nhưng phiên bản này cho phép ứng dụng của bạn xem đồng thời tất cả các mạng có sẵn. Vì vậy, lệnh gọi đến onLost(Network) có nghĩa là mạng đã bị ngắt kết nối vĩnh viễn, chứ không phải đó không còn là mạng mặc định nữa.

Ứng dụng tạo một NetworkRequest để cho ConnectivityManager biết loại mạng mà ứng dụng muốn theo dõi. Ví dụ sau đây cho biết cách tạo NetworkRequest cho một ứng dụng chỉ quan tâm đến các kết nối Internet không đo lượng dữ liệu:

Kotlin

val request = NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NET_CAPABILITY_INTERNET)
  .build()

connectivityManager.registerNetworkCallback(request, myNetworkCallback)

Java

NetworkRequest request = new NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NET_CAPABILITY_INTERNET)
  .build();

connectivityManager.registerNetworkCallback(request, myNetworkCallback);

Điều này có nghĩa là ứng dụng của bạn biết được mọi thay đổi liên quan đến các mạng không đo lượng dữ liệu trên hệ thống.

Đối với lệnh gọi lại mạng mặc định, một phiên bản của registerNetworkCallback(NetworkRequest, NetworkCallback, Handler) chấp nhận Handler để không tải luồng Connectivity của ứng dụng.

Gọi ConnectivityManager.unregisterNetworkCallback(NetworkCallback) khi lệnh gọi lại không còn phù hợp nữa. Một ứng dụng có thể đăng ký đồng thời nhiều lệnh gọi lại mạng.

Để thuận tiện, đối tượng NetworkRequest chứa các tính năng phổ biến mà hầu hết các ứng dụng cần, bao gồm:

Khi viết ứng dụng, hãy kiểm tra các giá trị mặc định để xem chúng có khớp với trường hợp sử dụng của bạn hay không, và xoá chúng nếu bạn muốn ứng dụng nhận thông báo về các mạng không có những tính năng này. Mặt khác, hãy thêm tính năng để tránh bị gọi khi có thay đổi về khả năng kết nối trong những mạng mà ứng dụng không tương tác.

Ví dụ: nếu ứng dụng của bạn cần gửi tin nhắn MMS, hãy thêm NET_CAPABILITY_MMS vào NetworkRequest để khỏi phải nhận thông báo về tất cả các mạng không thể gửi tin nhắn MMS. Bạn có thể thêm TRANSPORT_WIFI_AWARE nếu ứng dụng của bạn chỉ quan tâm đến khả năng kết nối Wi-Fi P2P. NET_CAPABILITY_INTERNETNET_CAPABILITY_VALIDATED rất hữu ích nếu bạn quan tâm đến khả năng chuyển dữ liệu qua một máy chủ trên Internet.

Trình tự gọi lại mẫu

Phần này mô tả trình tự các lệnh gọi lại mà một ứng dụng có thể nhận được nếu đăng ký cả một lệnh gọi lại mặc định lẫn một lệnh gọi lại thông thường trên thiết bị có kết nối di động. Trong ví dụ này, thiết bị sẽ kết nối với một điểm truy cập Wi-Fi đang hoạt động tốt, sau đó ngắt kết nối khỏi điểm truy cập đó. Ví dụ này cũng giả định rằng chế độ cài đặt Luôn bật dữ liệu di động đã được bật trên thiết bị.

Tiến trình như sau:

  1. Khi ứng dụng gọi registerNetworkCallback(), lệnh gọi lại ngay lập tức nhận lệnh gọi từ onAvailable(), onNetworkCapabilitiesChanged()onLinkPropertiesChanged() cho mạng di động vì chỉ có mạng đó mới dùng được. Nếu có sẵn một mạng khác, ứng dụng cũng sẽ nhận được lệnh gọi lại cho mạng khác đó.

    Sơ đồ trạng thái hiển thị sự kiện lệnh gọi lại mạng đăng ký và các lệnh gọi lại được sự kiện kích hoạt
    Hình 1. Trạng thái của ứng dụng sau khi gọi registerNetworkCallback().

  2. Sau đó, ứng dụng sẽ gọi registerDefaultNetworkCallback(). Lệnh gọi lại mạng mặc định bắt đầu nhận lệnh gọi đến onAvailable(), onNetworkCapabilitiesChanged()onLinkPropertiesChanged() cho mạng di động vì đây là mạng mặc định. Nếu một mạng khác không phải mạng mặc định hoạt động, ứng dụng sẽ không thể nhận các lệnh gọi cho mạng không phải mạng mặc định đó.

    Sơ đồ trạng thái cho thấy việc đăng ký sự kiện gọi lại mạng mặc định và các lệnh gọi lại được sự kiện kích hoạt
    Hình 2. Trạng thái của ứng dụng sau khi đăng ký một mạng mặc định.

  3. Sau đó, thiết bị sẽ kết nối với một mạng Wi-Fi (không đo lượng dữ liệu). Lệnh gọi lại mạng thông thường nhận lệnh gọi đến onAvailable(), onNetworkCapabilitiesChanged()onLinkPropertiesChanged() cho mạng Wi-Fi.

    Sơ đồ trạng thái cho thấy lệnh gọi lại được kích hoạt khi ứng dụng kết nối với một mạng mới
    Hình 3. Trạng thái của ứng dụng sau khi kết nối với một mạng Wi-Fi không đo lượng dữ liệu.

  4. Tại thời điểm này, mạng Wi-Fi có thể cần một chút thời gian để xác thực. Trong trường hợp này, các lệnh gọi onNetworkCapabilitiesChanged() cho lệnh gọi lại mạng thông thường không bao gồm tính năng NET_CAPABILITY_VALIDATED. Sau một thời gian ngắn, mạng đó sẽ nhận được lệnh gọi đến onNetworkCapabilitiesChanged(), trong đó các tính năng mới bao gồm NET_CAPABILITY_VALIDATED. Trong hầu hết các trường hợp, việc xác thực rất nhanh chóng.

    Khi mạng Wi-Fi xác thực, hệ thống sẽ ưu tiên mạng Wi-Fi hơn so với mạng di động, chủ yếu là do mạng Wi-Fi không đo lượng dữ liệu. Mạng Wi-Fi trở thành mạng mặc định, vì vậy, lệnh gọi lại mạng mặc định sẽ nhận được lệnh gọi đến onAvailable(), onNetworkCapabilitiesChanged()onLinkPropertiesChanged() cho mạng Wi-Fi đó. Mạng di động chuyển sang chế độ nền và lệnh gọi lại mạng thông thường sẽ nhận được lệnh gọi đến onLosing() cho mạng di động đó.

    Ví dụ này giả định rằng dữ liệu di động luôn bật trên thiết bị này, do đó, mạng di động không bao giờ ngắt kết nối. Nếu chế độ cài đặt này tắt, thì sau một thời gian, mạng di động sẽ ngắt kết nối và lệnh gọi lại mạng thông thường sẽ nhận được lệnh gọi đến onLost().

    Sơ đồ trạng thái cho thấy các lệnh gọi lại được kích hoạt khi kết nối mạng Wi-Fi xác thực
    Hình 4. Trạng thái của ứng dụng sau khi mạng Wi-Fi xác thực.

  5. Sau đó, thiết bị đột ngột ngắt kết nối khỏi Wi-Fi do Wi-Fi nằm ngoài vùng phủ sóng. Vì Wi-Fi ngắt kết nối nên lệnh gọi lại mạng thông thường sẽ nhận được lệnh gọi đến onLost() cho Wi-Fi. Do mạng di động là mạng mới mặc định nên lệnh gọi lại mạng mặc định sẽ nhận được lệnh gọi đến onAvailable(), onNetworkCapabilitiesChanged()onLinkPropertiesChanged() cho mạng di động.

    Sơ đồ trạng thái cho thấy các lệnh gọi lại được kích hoạt khi mất kết nối mạng Wi-Fi
    Hình 5. Trạng thái của ứng dụng sau khi ngắt kết nối khỏi mạng Wi-Fi.

Nếu chế độ cài đặt Luôn bật dữ liệu di động bị tắt, thì khi Wi-Fi ngắt kết nối, thiết bị sẽ cố gắng kết nối lại với mạng di động. Hình ảnh cũng tương tự nhưng các lệnh gọi onAvailable() bị trễ một chút, và lệnh gọi lại mạng thông thường cũng nhận được lệnh gọi đến onAvailable(), onNetworkCapabilitiesChanged()onLinkPropertiesChanged() vì chỉ có mạng di động là có sẵn.

Hạn chế về việc sử dụng mạng để chuyển dữ liệu

Việc có thể thấy một mạng có lệnh gọi lại mạng không có nghĩa là ứng dụng của bạn có thể dùng mạng để chuyển dữ liệu. Một số mạng không cung cấp kết nối Internet và một số mạng có thể bị hạn chế ở các ứng dụng đặc quyền. Để kiểm tra xem có kết nối Internet hay không, hãy xem NET_CAPABILITY_INTERNETNET_CAPABILITY_VALIDATED.

Việc sử dụng mạng trong nền cũng phải được kiểm tra quyền. Nếu muốn sử dụng một mạng trong nền, ứng dụng của bạn cần có quyền CHANGE_NETWORK_STATE.

Các ứng dụng có quyền này cho phép hệ thống cố gắng hiển thị một mạng không hoạt động, chẳng hạn như mạng di động khi thiết bị được kết nối với mạng Wi-Fi. Một ứng dụng như vậy gọi ConnectivityManager.requestNetwork(NetworkRequest, NetworkCallback) với NetworkCallback phải được gọi khi mạng đó xuất hiện.