Làm thế nào để kiểm tra truy cập internet trên Android? InetAddress không bao giờ hết


657

Tôi nhận được một AsyncTasknhiệm vụ phải kiểm tra quyền truy cập mạng vào tên máy chủ. Nhưng doInBackground()không bao giờ hết thời gian. Bất cứ ai cũng có một đầu mối?

public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {

    private Main main;

    public HostAvailabilityTask(Main main) {
        this.main = main;
    }

    protected Boolean doInBackground(String... params) {
        Main.Log("doInBackground() isHostAvailable():"+params[0]);

        try {
            return InetAddress.getByName(params[0]).isReachable(30); 
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;       
    }

    protected void onPostExecute(Boolean... result) {
        Main.Log("onPostExecute()");

        if(result[0] == false) {
            main.setContentView(R.layout.splash);
            return;
        }

        main.continueAfterHostCheck();
    }   
}

5
Để kiểm tra kết nối internet, có lẽ cách đáng tin cậy nhất là ping một trong những máy chủ tên chính, ví dụ như điều này có thể được thực hiện với if(Runtime.getRuntime().exec("/system/bin/ping -c 1 8.8.8.8").waitFor()==0) .... Xem câu trả lời của tôi để thực hiện tốt hơn về điều này. Btw câu trả lời được chấp nhận (và nhiều người khác ở đây) chỉ cần kiểm tra kết nối mạng chứ không phải internet.
Levite


4
Không sử dụng phương pháp ping, thay vào đó hãy sử dụng kiểm tra HTTP. ICMP bị chặn trên một số mạng, vì vậy ping sẽ không hoạt động. Ví dụ: nó hoạt động hoàn hảo trên wifi nhà tôi, nhưng nó không hoạt động khi tôi đang sử dụng dữ liệu di động trên mạng của Vodafone (ở Hungary). Hoặc kết hợp cả hai phương thức làm dự phòng, nhưng hãy cẩn thận vì WaitFor () sẽ đợi khoảng 20 giây ngay cả khi -w hoặc -W được sử dụng.
Tamás Bolvári


@ TamásBolvári: Thậm chí tốt hơn là giải quyết nó ở lớp tcp. Điều này sẽ giúp bạn tiến gần đến tốc độ của ICMP, với sự tin cậy của một yêu cầu HTTP. Tôi đã chỉnh sửa "ping answer" cho phù hợp.
Levite

Câu trả lời:


550

Kết nối mạng / truy cập Internet

  • isConnectedOrConnecting()(được sử dụng trong hầu hết các câu trả lời) kiểm tra mọi kết nối mạng
  • Để biết liệu có bất kỳ mạng nào trong số đó có truy cập internet hay không, hãy sử dụng một trong các cách sau

A) Ping một máy chủ (dễ dàng)

// ICMP 
public boolean isOnline() {
    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int     exitValue = ipProcess.waitFor();
        return (exitValue == 0);
    }
    catch (IOException e)          { e.printStackTrace(); }
    catch (InterruptedException e) { e.printStackTrace(); }

    return false;
}

+ có thể chạy trên luồng chính

- không hoạt động trên một số thiết bị cũ (Galays S3, v.v.), nó sẽ chặn một lúc nếu không có internet.

B) Kết nối với một Ổ cắm trên Internet (nâng cao)

// TCP/HTTP/DNS (depending on the port, 53=DNS, 80=HTTP, etc.)
public boolean isOnline() {
    try {
        int timeoutMs = 1500;
        Socket sock = new Socket();
        SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);

        sock.connect(sockaddr, timeoutMs);
        sock.close();

        return true;
    } catch (IOException e) { return false; }
}

+rất nhanh (dù bằng cách nào), hoạt động trên tất cả các thiết bị, rất đáng tin cậy

- không thể chạy trên luồng UI

Điều này hoạt động rất đáng tin cậy, trên mọi thiết bị, và rất nhanh. Nó cần phải chạy trong một nhiệm vụ riêng biệt (ví dụ ScheduledExecutorServicehoặc AsyncTask).

Câu hỏi có thể

  • Có thực sự đủ nhanh?

    Vâng, rất nhanh ;-)

  • Không có cách nào đáng tin cậy để kiểm tra internet, ngoài việc kiểm tra một cái gì đó trên internet?

    Không xa như tôi biết, nhưng hãy cho tôi biết, và tôi sẽ chỉnh sửa câu trả lời của mình.

  • Nếu DNS bị sập thì sao?

    Google DNS (ví dụ 8.8.8.8) là DNS công cộng lớn nhất trên thế giới. Tính đến năm 2013, nó đã phục vụ 130 tỷ yêu cầu mỗi ngày. Hãy nói rằng, ứng dụng của bạn có thể không phải là cuộc nói chuyện trong ngày.

  • Những quyền nào được yêu cầu?

    <uses-permission android:name="android.permission.INTERNET" />

    Chỉ cần truy cập internet - thật bất ngờ ^^ (Btw bạn đã bao giờ nghĩ đến, làm thế nào một số phương pháp được đề xuất ở đây thậm chí có thể có một keo dán từ xa về truy cập internet, mà không có sự cho phép này?)

 

Thêm: AsyncTaskVí dụ một lần

class InternetCheck extends AsyncTask<Void,Void,Boolean> {

    private Consumer mConsumer;
    public  interface Consumer { void accept(Boolean internet); }

    public  InternetCheck(Consumer consumer) { mConsumer = consumer; execute(); }

    @Override protected Boolean doInBackground(Void... voids) { try {
        Socket sock = new Socket();
        sock.connect(new InetSocketAddress("8.8.8.8", 53), 1500);
        sock.close();
        return true;
    } catch (IOException e) { return false; } }

    @Override protected void onPostExecute(Boolean internet) { mConsumer.accept(internet); }
}

///////////////////////////////////////////////////////////////////////////////////
// Usage

    new InternetCheck(internet -> { /* do something with boolean response */ });

Thêm: RxJava/RxAndroidVí dụ một lần bắn (Kotlin)

fun hasInternetConnection(): Single<Boolean> {
  return Single.fromCallable {
    try {
      // Connect to Google DNS to check for connection
      val timeoutMs = 1500
      val socket = Socket()
      val socketAddress = InetSocketAddress("8.8.8.8", 53)

      socket.connect(socketAddress, timeoutMs)
      socket.close()

      true
    } catch (e: IOException) {
      false
    }
  }
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
}

///////////////////////////////////////////////////////////////////////////////////
    // Usage

    hasInternetConnection().subscribe { hasInternet -> /* do something */}

22
Đây là sự bình an tuyệt vời của mã! Tôi thấy nó rất hữu ích trên các thiết bị sử dụng thẻ trả trước! Khi hết tiền, họ có sẵn truy cập internet, nhưng không có internet. Vì vậy, chỉ cần kiểm tra kết nối sẽ không làm. CẢM ƠN BẠN!
Blejzer

10
Hãy ghi nhớ cách tiếp cận này là một cách chặn vì vậy bạn không nên thực hiện nó trong giao diện người dùng
Sergii

36
@Levit Đây phải là câu trả lời được chấp nhận. Trên câu trả lời chỉ cần kiểm tra Mạng n KHÔNG LIÊN KẾT INTERNET . Và vâng, điều này rất nhanh. Cảm ơn. Do đó upvote.
Roon13

9
Giải pháp này không hoạt động cho tất cả các thiết bị. Một số thiết bị luôn trả về 2 như @Salmaan đã nêu. Các thiết bị tôi đã kiểm tra có kết nối internet và mục tiêu ping là máy chủ DNS của Google - đang đáp ứng các yêu cầu ping. Tôi nghĩ rằng một số nhà cung cấp không cho phép yêu cầu ping. Ví dụ: tôi đã thử nghiệm với máy tính bảng Samsung 10.1 (4.3) và giải pháp không hoạt động. Khi tôi chạy lệnh ping thông qua tiện ích dòng lệnh, tôi gặp lỗi về quyền. Lệnh cũng không hoạt động trên trình giả lập. Hãy cẩn thận khi sử dụng giải pháp này.
Eren Yilmaz

9
Cách tiếp cận này không hoạt động trên tất cả các điện thoại. Nó không thành công, ví dụ như trên Samsung Galaxy S3. Xem ở đây: Tại sao ping hoạt động trên một số thiết bị mà không phải các thiết bị khác?
Adil Hussain

1032

Nếu thiết bị đang ở chế độ máy bay (hoặc có lẽ là trong những tình huống khác, nơi không có mạng có sẵn), cm.getActiveNetworkInfo()sẽ được null, vì vậy bạn cần phải thêm một nullkiểm tra.

Đã sửa đổi ( giải pháp của Eddie ) bên dưới:

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

Đồng thời thêm quyền sau vào AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Một điểm nhỏ khác, nếu bạn thực sự cần một kết nối mạng tại thời điểm nhất định, thì có thể tốt hơn là sử dụng netInfo.isConnected()hơn là netInfo.isConnectedOrConnecting. Tôi đoán điều này tùy thuộc vào trường hợp sử dụng riêng lẻ.


109
Bạn vẫn nên và cần kiểm tra ngoại lệ thời gian chờ http vì có thể có tình huống khi mạng được kết nối nhưng sẽ không có kết nối internet thực tế vì cách duy nhất để truy cập là thông qua VPN - theo cách này, bạn có, theo cách này ví dụ, kết nối WI-FI nhưng không có lưu lượng truy cập internet thực tế. Một tình huống khác là một máy chủ bị treo. Đây là 2 vấn đề mà tôi đã chạy gần đây và trình quản lý kết nối sẽ không giúp được gì ở đó.
nửa đêm

21
Tôi đồng ý với nửa đêm và Pintu, câu trả lời này không phải là câu trả lời được chấp nhận, nó không liên quan gì đến việc kiểm tra thời tiết bạn đang truy cập internet. Ví dụ: nếu điện thoại được kết nối với mạng WiFi có cổng bị khóa, như ở khách sạn, chức năng này sẽ trả về không đúng sự thật. Câu trả lời đúng là ping máy chủ trên internet công cộng.
miguel

9
khi không có internet hoạt động cho bộ định tuyến của tôi, nếu tôi kết nối với bộ định tuyến qua wifi thì mã trên sẽ trả về đúng. Nhưng, nó không phải là như vậy, phải không? Bạn có thể giúp tôi không
MoHaN K RaJ

5
Tôi đã phải thêm Bối cảnh, trong context.getSystemServicehoặc nó không hoạt động. Tôi đã có manh mối của mình ở đây androidhive.info/2012/07/ Kẻ
Francisco Corrales Morales

1
Cách tốt đẹp để kiểm tra tính khả dụng của mạng. Nhưng làm thế nào để kiểm tra truy cập internet?
Tamás Bolvári

296

Không cần phải phức tạp. Cách đơn giản nhất và khung là sử dụng ACCESS_NETWORK_STATEquyền và chỉ tạo một phương thức được kết nối

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    return cm.getActiveNetworkInfo() != null && 
       cm.getActiveNetworkInfo().isConnectedOrConnecting();
}

Bạn cũng có thể sử dụng requestRouteToHostnếu bạn có một máy chủ particualr và loại kết nối (wifi / di động) trong tâm trí.

Bạn cũng sẽ cần:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

trong bảng kê khai Android của bạn.


82
tốt hơn là thực hiện kiểm tra null ở mức cm.getActiveNetworkInfo () nó đã ném null nếu không có mạng hoạt động.
Samuel

xem stackoverflow.com/a/11691676/1979773 để biết thêm chi tiết về requestRouteTohost ()
Spartako

Tôi đã phải thêm Bối cảnh, trong context.getSystemServicehoặc nó không hoạt động. Tôi đã có manh mối của mình ở đây androidhive.info/2012/07/ Kẻ
Francisco Corrales Morales

9
Giải pháp này sẽ trở lại đúng nếu bạn được kết nối với điểm truy cập WiFi, ngay cả khi điểm truy cập này KHÔNG có kết nối internet.
Josh


63

Để đi getActiveNetworkInfo()làm, bạn cần thêm phần sau vào bảng kê khai.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Điều này chắc chắn phải được trả lời đúng (lãng phí quá nhiều thời gian để tìm ra cái quái gì là sai).
Indrek Kõue

2
Quyền INTERNET KHÔNG cần thiết cho việc này, chỉ cần ACCESS_NETWORK_STATE. INTERNET chỉ cần thiết nếu bạn thực sự thực hiện kết nối đến các địa điểm từ xa, không truy vấn trạng thái radio của thiết bị.
Tom

3
Câu trả lời của bạn hiện không thực sự là một câu trả lời, nó chỉ là một bổ sung tương đối nhỏ cho các câu trả lời khác. Nếu tất cả các câu trả lời khác không có ở đây, câu trả lời của bạn có hợp lý không? Không hẳn vậy. Bởi vì nếu tốt hơn là mở rộng câu trả lời của bạn bằng mã về cách sử dụng hoặc xóa câu trả lời của bạn và thêm thông tin vào câu trả lời khác (bạn sẽ không mất bất kỳ danh tiếng nào)
Tim

Hãy cẩn thận getActiveNetworkInfo()bị phản đối trong cấp độ API 29.
Stack Overflow

46

Hãy xem lớp ConnectivityManager. Bạn có thể sử dụng lớp này để nhận thông tin về các kết nối hoạt động trên máy chủ. http://developer.android.com/reference/android/net/ConnectivityManager.html

EDIT: Bạn có thể sử dụng

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE) 

hoặc là

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_WIFI) 

và phân tích enum chi tiết của đối tượng NetworkInfo được trả về

EDIT EDIT: Để tìm hiểu xem bạn có thể truy cập máy chủ không, bạn có thể sử dụng

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .requestRouteToHost(TYPE_WIFI, int hostAddress)

Rõ ràng, tôi đang sử dụng Context.getSystemService (Context.CONNECTIVITY_SERVICE) làm proxy để nói

ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();

Không chắc chắn, nhưng đây có vẻ giống như mã để kiểm tra loại kết nối mạng hiện tại tôi đang sử dụng. Ví dụ như im trên WiFi, không có gì bảo đảm rằng bạn nhà wifi router được kết nối với internett ... để kiểm tra xem bạn thực sự cần phải làm một yêu cầu đến một internetserver ...
Vidar Vestnes

1
Có một lỗi trong phần EDIT EDIT, tôi đã bỏ qua lệnh gọi requestRouteTohost (). Đọc lại câu trả lời ngay bây giờ :)
Chinmay Kanchi

requestRouteTohost đã không được chấp nhận.
Jahaziel

46

kiểm tra mã này ... nó làm việc cho tôi :)

public static void isNetworkAvailable(final Handler handler, final int timeout) {
    // ask fo message '0' (not connected) or '1' (connected) on 'handler'
    // the answer must be send before before within the 'timeout' (in milliseconds)

    new Thread() {
        private boolean responded = false;   
        @Override
        public void run() { 
            // set 'responded' to TRUE if is able to connect with google mobile (responds fast) 
            new Thread() {      
                @Override
                public void run() {
                    HttpGet requestForTest = new HttpGet("http://m.google.com");
                    try {
                        new DefaultHttpClient().execute(requestForTest); // can last...
                        responded = true;
                    } 
                    catch (Exception e) {
                    }
                } 
            }.start();

            try {
                int waited = 0;
                while(!responded && (waited < timeout)) {
                    sleep(100);
                    if(!responded ) { 
                        waited += 100;
                    }
                }
            } 
            catch(InterruptedException e) {} // do nothing 
            finally { 
                if (!responded) { handler.sendEmptyMessage(0); } 
                else { handler.sendEmptyMessage(1); }
            }
        }
    }.start();
}

Sau đó, tôi xác định xử lý:

Handler h = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        if (msg.what != 1) { // code if not connected

        } else { // code if connected

        }   
    }
};

... và khởi chạy thử nghiệm:

isNetworkAvailable(h,2000); // get the answser within 2000 ms

3
Google đang suy sụp là gì? Điều đó cũng đòi hỏi phải có sự cho phép của INTERNET, không cần thiết cho nhiệm vụ nhất định. Cuối cùng, điều đó tiêu thụ dữ liệu (ngay cả khi không đáng kể). Điều này chỉ giống như một loại bùn như vậy.
Tom

28
@Tom để công bằng, đây có lẽ là câu trả lời đúng duy nhất. Các ví dụ khác chỉ hiển thị nếu một kết nối mạng là có sẵn và / hoặc nếu có một kết nối vào mạng đó, nhưng không trả lời câu hỏi nếu mạng mà thực sự cũng có thể tạo ra một kết nối từ xa (ví dụ đến một trang web). Vì vậy, điều này trả lời các áp phích Q, và các câu trả lời khác không
slinden77

2
@dmmh Vâng, điều đó thật không may đúng với những gì tôi đã thấy với các API Android. Có lẽ một ping đơn giản có thể tốt hơn, stackoverflow.com/questions/3905353/ . Nếu bạn thực sự lo ngại, bạn thậm chí có thể đưa vào danh sách IP để ping, bởi vì trong khi có một cơ hội rất nhỏ Google sẽ không hoạt động, thì có một cơ hội nhỏ hơn nữa là Google, Bing và Yahoo sẽ ngừng hoạt động cùng ngày . Chỉ là suy nghĩ của tôi.
Tom

10
Không có điểm nào trong việc kiểm tra này. Nếu bạn định dành thời gian hệ thống và tài nguyên mạng để kết nối với Google, bạn có thể đã sử dụng chúng thay vì kết nối với tài nguyên mà bạn thực sự quan tâm.
Benjamin

16
Ở Trung Quốc Google đã bị chặn !!
Anthone

26

Tìm thấy tại và sửa đổi (!) Từ liên kết này :

Trong tệp kê khai của bạn thêm ít nhất:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Bạn có thể đã có quyền INTERNET nếu bạn đang truy cập nó. Sau đó, một hàm boolean cho phép kiểm tra kết nối là:

private boolean checkInternetConnection() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    // test for connection
    if (cm.getActiveNetworkInfo() != null
            && cm.getActiveNetworkInfo().isAvailable()
            && cm.getActiveNetworkInfo().isConnected()) {
        return true;
    } else {
        Log.v(TAG, "Internet Connection Not Present");
        return false;
    }
}

18

Tôi đã tạo mã này, nó là đơn giản nhất và nó chỉ là một boolean. bằng cách hỏiif(isOnline()){

Bạn nhận được nếu có kết nối và nếu nó có thể kết nối với một trang mã trạng thái 200(kết nối ổn định).

Hãy chắc chắn để thêm chính xác INTERNETACCESS_NETWORK_STATEquyền.

public boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnected()) {
        try {
            URL url = new URL("http://www.google.com");
            HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
            urlc.setConnectTimeout(3000);
            urlc.connect();
            if (urlc.getResponseCode() == 200) {
                return new Boolean(true);
            }
        } catch (MalformedURLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return false;
}

6
Có lẽ bạn nên thay thế 200 bằng httpURLConnection.HTTP_OK
Yash

5
Nếu Google ngừng hoạt động thì sao?
Yauraw Gadav

12

Nó làm việc cho tôi:

Để xác minh tính khả dụng của mạng:

private Boolean isNetworkAvailable() {
ConnectivityManager connectivityManager 
      = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();}

Để xác minh truy cập internet:

public Boolean isOnline() {
    try {
        Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
        int returnVal = p1.waitFor();
        boolean reachable = (returnVal==0);
        return reachable;
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return false;
}

Đây là một giải pháp tuyệt vời để kiểm tra nếu một máy chủ si lên, hoạt động thực sự tốt. cảm ơn!
Williew

1
isOnline () hoàn toàn không nên chạy trên luồng chính, vì nếu có tín hiệu wi-fi nhưng không có internet thì sẽ mất quá nhiều thời gian và chặn luồng chính.
nhục nhã

9

Có nhiều hơn một cách

Cách đầu tiên, ngắn nhất nhưng không hiệu quả

Chỉ cần có sự cho phép của nhà nước

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Sau đó, phương pháp này,

 public boolean activeNetwork () {
        ConnectivityManager cm =
                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null &&
                activeNetwork.isConnected();

        return isConnected;

    }

Như đã thấy trong câu trả lời ConnectivityManagerlà một giải pháp, tôi chỉ thêm nó vào một phương thức, đây là một phương pháp đơn giản hóa tất cả sử dụng
ConnectivityManagertrả về true nếu có truy cập mạng không truy cập Internet, nghĩa là nếu WiFi của bạn được kết nối với bộ định tuyến nhưng bộ định tuyến không có internet trả về đúng, nó kiểm tra tính khả dụng của kết nối

Thứ hai, cách hiệu quả

Mạng nhà nước và quyền Internet cần thiết

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

Rồi lớp này,

 public class CheckInternetAsyncTask extends AsyncTask<Void, Integer, Boolean> {

        private Context context;

        public CheckInternetAsyncTask(Context context) {
            this.context = context;
        }

        @Override
        protected Boolean doInBackground(Void... params) {

            ConnectivityManager cm =
                    (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

            assert cm != null;
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            boolean isConnected = activeNetwork != null &&
                    activeNetwork.isConnected();


            if (isConnected) {
                try {
                    HttpURLConnection urlc = (HttpURLConnection)
                            (new URL("http://clients3.google.com/generate_204")
                                    .openConnection());
                    urlc.setRequestProperty("User-Agent", "Android");
                    urlc.setRequestProperty("Connection", "close");
                    urlc.setConnectTimeout(1500);
                    urlc.connect();
                    if (urlc.getResponseCode() == 204 &&
                            urlc.getContentLength() == 0)
                        return true;

                } catch (IOException e) {
                    Log.e("TAG", "Error checking internet connection", e);
                    return false;
                }
            } else {
                Log.d("TAG", "No network available!");
                return false;
            }


            return null;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            Log.d("TAG", "result" + result);

            if(result){
                // do ur code
            }

        }


    }

Gọi CheckInternetAsyncTask

new CheckInternetAsyncTask(getApplicationContext()).execute();

Một số giải thích: -

  • bạn phải kiểm tra Internet AsyncTask, nếu không nó có thể bị ném android.os.NetworkOnMainThreadExceptiontrong một số trường hợp

  • ConnectivityManager được sử dụng để kiểm tra truy cập mạng nếu đúng gửi yêu cầu (Ping)

  • Yêu cầu gửi đến http://clients3.google.com/generate_204, URL nổi tiếng này được biết là trả về một trang trống có trạng thái HTTP 204, điều này nhanh hơn và hiệu quả hơn http://www.google.com, đọc điều này . nếu bạn có trang web, bạn nên đặt trang web của mình thay vì google, chỉ khi bạn sử dụng trang web trong ứng dụng

  • Thời gian chờ có thể thay đổi phạm vi (20ms -> 2000ms), 1500ms thường được sử dụng


2
Câu hỏi tuyệt vời, thật đáng buồn khi bạn không có nhiều điểm hơn. Đây phải là câu trả lời chính xác.
Jhon Fredy Trujillo Ortega

Tôi mới sử dụng Android. Mặc dù vậy, đây là câu trả lời được bảo vệ tốt và nó được chú ý nhiều hơn @ 7569106
Mazen Embaby

1
câu trả lời tốt nhất và đầy đủ, cảm ơn bạn. nếu ai đó có thông báo trang web thì điều kiện đó phải thích urlc.getResponseCode () == 200 và không cần kiểm tra urlc.getContentL wavel () == 0
ISF

tùy chọn thứ hai của bạn gặp sự cố tôi không biết tại sao
nafees ahmed

nó đóng băng ứng dụng
an toàn vào

8

Trong tất cả mọi thứ tôi đã thấy cho đến nay cách ngắn nhất và sạch nhất nên là:

public final static boolean isConnected( Context context )
{   
   final ConnectivityManager connectivityManager = 
         (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );  
   final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();    
   return networkInfo != null && networkInfo.isConnected();
}

PS: Điều này không ping bất kỳ máy chủ nào, nó chỉ kiểm tra kết nối, vì vậy nếu bộ định tuyến của bạn không có kết nối internet và thiết bị của bạn được kết nối với nó thì phương thức này sẽ trở lại đúng mặc dù bạn không có internet.
Đối với thử nghiệm thực tế, tôi khuyên bạn nên thực hiện yêu cầu HttpHead (ví dụ: www.google.com) và kiểm tra trạng thái, nếu 200 OK thì mọi thứ đều ổn và thiết bị của bạn có kết nối internet.


Tôi muốn đưa phương thức này vào một lớp toàn cầu vì vậy tôi phải sử dụng phiên bản này để tôi có thể vượt qua Bối cảnh từ Hoạt động mà tôi đang gọi nó từ đó. Cảm ơn!
RyanG

8

Đây là phương pháp tôi sử dụng:

public boolean isNetworkAvailable(final Context context) {
    return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;
}

Thậm chí tốt hơn, kiểm tra để đảm bảo rằng nó được "kết nối":

public boolean isNetworkAvailable(final Context context) {
    final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
    return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
}

Đây là cách sử dụng phương pháp:

if (isNetworkAvailable(context)) {
    // code here
} else {
    // code
}

Cần có sự cho phép:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

https://stackoverflow.com/a/16124915/950427


7

Một trường hợp sử dụng quan trọng trên thiết bị di động để đảm bảo tồn tại kết nối thực tế. Đây là một vấn đề phổ biến khi người dùng di động truy cập mạng Wifi bằng "Cổng thông tin bắt buộc", trong đó họ cần đăng nhập. Tôi sử dụng chức năng chặn này trong nền để đảm bảo tồn tại kết nối.

/*
 * Not Thread safe. Blocking thread. Returns true if it
 * can connect to URL, false and exception is logged.
 */
public boolean checkConnectionHttps(String url){
    boolean responded = false;
    HttpGet requestTest = new HttpGet(url);
    HttpParams params = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(params, 3000);
    HttpConnectionParams.setSoTimeout(params, 5000);
    DefaultHttpClient client = new DefaultHttpClient(params);
    try {
        client.execute(requestTest);
        responded = true;
    } catch (ClientProtocolException e) {
        Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
    } catch (IOException e) {
        Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
        e.printStackTrace();
    }
    return responded;
}

3
+1 để thực sự kiểm tra kết nối đầu cuối. Tuy nhiên, đối với tình huống "Cổng thông tin bắt buộc", tôi đã thấy rằng nhiều người sẽ vượt qua bài kiểm tra trên ngay cả khi bạn chưa đăng nhập - bạn nhận được trang đăng nhập và 200 phản hồi cho dù bạn yêu cầu url nào. Vì vậy, tôi cố gắng truy cập một trang trên tên miền của riêng tôi mà tôi biết là không tồn tại và đảm bảo rằng tôi nhận được 404. Thay vào đó, bạn có thể nhấn một trang hiện có đã biết, đảm bảo rằng bạn nhận được 200 và kiểm tra nội dung được trả lại để đảm bảo rằng đó là những gì bạn mong đợi.
GreyBeardedGeek

6

Bạn có thể lặp lại trên tất cả các kết nối mạng và chọn xem có ít nhất một kết nối khả dụng hay không:

public boolean isConnected() {
    boolean connected = false;

    ConnectivityManager cm = 
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        NetworkInfo[] netInfo = cm.getAllNetworkInfo();

        for (NetworkInfo ni : netInfo) {
            if ((ni.getTypeName().equalsIgnoreCase("WIFI")
                    || ni.getTypeName().equalsIgnoreCase("MOBILE"))
                    && ni.isConnected() && ni.isAvailable()) {
                connected = true;
            }

        }
    }

    return connected;
}

6

Đối với tôi, đó không phải là một cách thực hành tốt để kiểm tra trạng thái kết nối trong lớp Activity, bởi vì

ConnectivityManager cm =
    (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

nên được gọi ở đó hoặc bạn cần đẩy đối tượng Activity (ngữ cảnh) của mình xuống lớp trình xử lý kết nối để có thể kiểm tra trạng thái kết nối ở đó Khi không có kết nối (wifi, mạng) Tôi bắt gặp ngoại lệ UnknownhostException :

JSONObject jObj = null;
Boolean responded = false;
HttpGet requestForTest = new HttpGet("http://myserver.com");
try {
    new DefaultHttpClient().execute(requestForTest);
    responded = true;
} catch (UnknownHostException e) {
    jObj = new JSONObject();
    try {
        jObj.put("answer_code", 1);
        jObj.put("answer_text", "No available connection");
    } catch (Exception e1) {}
    return jObj;
} catch (IOException e) {
    e.printStackTrace();
}

Theo cách này tôi có thể xử lý trường hợp này cùng với các trường hợp khác trong cùng một lớp (máy chủ của tôi luôn phản hồi lại bằng chuỗi json)


6

Nó làm việc cho tôi. Hãy thử nó.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    try {
        URL url = new URL("http://stackoverflow.com/posts/11642475/edit" );
        //URL url = new URL("http://www.nofoundwebsite.com/" );
        executeReq(url);
        Toast.makeText(getApplicationContext(), "Webpage is available!", Toast.LENGTH_SHORT).show();
    }
    catch(Exception e) {
        Toast.makeText(getApplicationContext(), "oops! webpage is not available!", Toast.LENGTH_SHORT).show();
    }
}

private void executeReq(URL urlObject) throws IOException
{
    HttpURLConnection conn = null;
    conn = (HttpURLConnection) urlObject.openConnection();
    conn.setReadTimeout(30000);//milliseconds
    conn.setConnectTimeout(3500);//milliseconds
    conn.setRequestMethod("GET");
    conn.setDoInput(true);

    // Start connect
    conn.connect();
    InputStream response =conn.getInputStream();
    Log.d("Response:", response.toString());
}}

Câu trả lời này không thể hoạt động ngay bây giờ, vì chúng tôi không thể truy cập mạng trên luồng chính ngay bây giờ.
正宗 白

1
Ý tôi là từ API cấp 11, cái này không hoạt động. Lý do: developer.android.com/reference/android/os/ . Nếu nó hoạt động cho bạn, điều đó có nghĩa là bạn đang chạy mã này trên thiết bị Android cũ. (trước GB).
正宗 白

StrictMode.ThreadPolicy chính sách = new StrictMode.ThreadPolicy.Builder () .permit ALL (). Build (); StrictMode.setThreadPolicy (chính sách); thêm hai dòng này vào chương trình của bạn để tránh ngoại lệ luồng chính của mạng
selva_pollachi

Ok, tôi không nên nói điều này không thể hoạt động, tôi nên nói nó có thể hoạt động (theo phiên bản cũ hoặc cài đặt Strictmode) nhưng không được khuyến khích. Điều này có thể gây ra ANR dễ dàng. (Với cấu hình thời gian chờ quá cao trong httpurlconnection)
正宗 白

ya..bạn nói đúng .. chỉ cần tôi đặt cái này vì đây cũng là một trong những cách.
selva_pollachi

6

Phương pháp này cung cấp cho bạn tùy chọn cho một phương thức thực sự nhanh (đối với phản hồi thời gian thực) hoặc phương pháp chậm hơn (đối với một lần kiểm tra yêu cầu độ tin cậy)

public boolean isNetworkAvailable(bool SlowButMoreReliable) {
    bool Result = false; 
    try {
        if(SlowButMoreReliable){
            ConnectivityManager MyConnectivityManager = null;
            MyConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo MyNetworkInfo = null;
            MyNetworkInfo = MyConnectivityManager.getActiveNetworkInfo();

            Result = MyNetworkInfo != null && MyNetworkInfo.isConnected();

        } else
        {
            Runtime runtime = Runtime.getRuntime();
            Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");

            int i = ipProcess.waitFor();

            Result = i== 0;

        }

    } catch(Exception ex)
    {
        //Common.Exception(ex); //This method is one you should have that displays exceptions in your log
    }
    return Result;
}

5

Tôi đang sử dụng mã này thay vì InetAddress:

    try {

        URL url = new URL("http://"+params[0]);

        HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
        urlc.setRequestProperty("User-Agent", "Android Application:"+Z.APP_VERSION);
        urlc.setRequestProperty("Connection", "close");
        urlc.setConnectTimeout(1000 * 30); // mTimeout is in seconds
        urlc.connect();
        if (urlc.getResponseCode() == 200) {
            Main.Log("getResponseCode == 200");
            return new Boolean(true);
        }
    } catch (MalformedURLException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Sẽ thật tuyệt nếu bạn đã làm rõ nếu IOException có nghĩa là không có kết nối internet và mức độ tin cậy của nó.
Milad.Nozari

5

Việc kiểm tra trạng thái kết nối mạng / internet của Android không phức tạp. Lớp dưới đây DetectConnectionsẽ giúp bạn kiểm tra trạng thái này:

import android.content.Context;
import android.net.ConnectivityManager;

public class DetectConnection {
    public static boolean checkInternetConnection(Context context) {
        ConnectivityManager con_manager = (ConnectivityManager) context
                                .getSystemService(Context.CONNECTIVITY_SERVICE);

        if (con_manager.getActiveNetworkInfo() != null
            && con_manager.getActiveNetworkInfo().isAvailable()
            && con_manager.getActiveNetworkInfo().isConnected()) {
                return true;
        } else {
            return false;
        }
    }
}

Để biết thêm chi tiết, hãy truy cập Cách kiểm tra trạng thái kết nối mạng / Internet của Android


5

Cách tiếp cận tốt nhất:

public static boolean isOnline() {
    try {
    InetAddress.getByName("google.com").isReachable(3);

    return true;
    } catch (UnknownHostException e){
    return false;
    } catch (IOException e){
    return false;
    }
    }

1
Tôi thích cách tiếp cận này nhưng tôi phải chỉ ra một số điều. isReachable () trả về một boolean, do đó thay vì trả về true trong phần thử, bạn có thể làm như boolean được kết nối = InetAddress.getByName ("google.com"). isReachable (3); sau đó kết nối trở lại. Ngoài ra, isReachizable ném ngoại lệ IOException và IllegalArgumentException, do đó, sẽ là một ý tưởng tốt để thay thế UnknownhostException bằng IllegalArgumentException và bao gồm một lần bắt thứ ba: Catch (Exception E).
Yash

2
Nhưng sau đó, isReachable sử dụng ICMP có thể yêu cầu quyền root và sử dụng cổng 7 thường không có dịch vụ chạy trên các hệ thống mới nhất. Do đó, cách tốt nhất để kiểm tra tuyến đến dịch vụ trực tuyến là bằng TCP thông thường; do đó bỏ phiếu xuống.
Yash

5

Sau đây là mã từ Utilslớp của tôi :

public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager 
              = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

5
public class Network {

Context context;

public Network(Context context){
    this.context = context;
}

public boolean isOnline() {
    ConnectivityManager cm =
            (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null &&
                          activeNetwork.isConnectedOrConnecting();
}

}

Như tất cả những người khác không đọc được vấn đề thông qua, điều này không giải quyết được vấn đề, vì nó không thực sự kiểm tra kết nối với internet. Kết nối với điểm phát wifi cục bộ sẽ trở lại đúng, ngay cả khi điểm phát sóng đó không cho phép bạn truy cập internet.
Pedro Pombeiro

5

Bạn có thể sử dụng phương pháp này để phát hiện tính khả dụng của mạng

public static boolean isDeviceOnline(Context context) {
        boolean isConnectionAvail = false;
        try {
            ConnectivityManager cm = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            return netInfo.isConnected();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isConnectionAvail;
    }

5

Tôi đã áp dụng giải pháp được cung cấp bởi @Levit và đã tạo chức năng sẽ không gọi thêm Yêu cầu http.

Nó sẽ giải quyết lỗi Unable to Resolve Host

public static boolean isInternetAvailable(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork == null) return false;

    switch (activeNetwork.getType()) {
        case ConnectivityManager.TYPE_WIFI:
            if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
                    activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
                    isInternet())
                return true;
            break;
        case ConnectivityManager.TYPE_MOBILE:
            if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
                    activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
                    isInternet())
                return true;
            break;
        default:
            return false;
    }
    return false;
}

private static boolean isInternet() {

    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int exitValue = ipProcess.waitFor();
        Debug.i(exitValue + "");
        return (exitValue == 0);
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }

    return false;
}

Bây giờ gọi nó như thế nào,

if (!isInternetAvailable(getActivity())) {
     //Show message
} else {
     //Perfoem the api request
}

4

Điều này được đề cập trong các tài liệu Android http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html


1
Nhưng phương pháp được mô tả ở đó không thực sự kiểm tra kết nối Internet, nó chỉ kiểm tra xem kết nối có được thiết lập hay không (có truy cập Internet hay không). Tiêu đề của tài liệu chính thức đó là thực sự sai lệch.
Tiago

2
Đưa ra một câu trả lời cho câu hỏi tốt hơn là chỉ đăng một liên kết đến thông tin. Nếu liên kết bị chết thì sao? Chúng tôi sẽ không có câu trả lời.
Jose Llausas

4

Tôi đã trải qua tất cả các câu trả lời và tôi đưa ra câu trả lời của riêng mình, lần đầu tiên kiểm tra xem Internet có khả dụng không và nếu Internet có sẵn thì nó sẽ kiểm tra xem nó có hoạt động hay không.

Tôi đã bao gồm tất cả các phương thức và lớp cần thiết để kiểm tra kết nối Internet đang hoạt động.

NetworkUtils. Class

public class NetworkUtils {

    public static final int STATUS_CONNECTED = 0 ;

    public static boolean isInternetAvailable(Context ctx){
        ConnectivityManager cm = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    }

    public static int isInternetActiveWithPing() {
        try {
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
            int exitValue = process.waitFor();
            return exitValue;
        } catch (Exception ex) {
            return -1;
        }
    }

    public static boolean isInternetActiveWithInetAddress() {
        try {
            InetAddress inetAddress = InetAddress.getByName("www.google.com");
            return inetAddress != null && !inetAddress.toString().equals("");
        } catch (Exception ex) {
            return false;
        }
    }

    public static void displayInternetConnectionMessage(Context ctx){
        Toast.makeText(ctx, "Check Internet Connection", Toast.LENGTH_SHORT).show();
    }
}

Bạn có thể kiểm tra xem Internet có hoạt động hay không bằng cách sử dụng mã dưới đây:

 private void checkInternetConnection() {
        if (NetworkUtils.isInternetAvailable(this)) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (NetworkUtils.isInternetActiveWithPing() == NetworkUtils.STATUS_CONNECTED) {
                        performNetworkingOperations();
                    } else {
                        if (NetworkUtils.isInternetActiveWithInetAddress()) {
                            performNetworkingOperations();
                        } else {
                            displayConnectionMessage();
                        }
                    }
                }
            }).start();

        } else {
            displayConnectionMessage();
        }
    }

    private void performNetworkingOperations() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, "Internet is Available", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void displayConnectionMessage() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                NetworkUtils.displayInternetConnectionMessage(MainActivity.this);
            }
        });
    }

Gói luồng tốt hơn trong NetworkUtils của bạn và do đó "buộc" nhà phát triển không sử dụng sai phương pháp của bạn
Ewoks

Để loại bỏ thêm một nếu điều kiện. if ((NetworkUtils.isInternetActiveWithPing () == NetworkUtils.STATUS_CONNECTED) || NetworkUtils.isInternetActiveWithInetAddress ()) {// Đỗ Mạng lưới hoạt động} else {// Thông báo lỗi}
Jawad Zeb

4

Rất quan trọng để kiểm tra xem chúng tôi có kết nối với isAv Available () không và nếu có thể thiết lập kết nối với isConnected ()

private static ConnectivityManager manager;

public static boolean isOnline(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    return networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
}

và bạn có thể hủy diệt loại WiFi hoạt động của mạng :

public static boolean isConnectedWifi(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
}

hoặc điện thoại di động Móvil :

public static boolean isConnectedMobile(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
}

đừng quên các quyền:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   <uses-permission android:name="android.permission.INTERNET" />

Tóm tắt tốt đẹp của các thành phần kết nối thiết bị, chỉ cần bọc chúng trong các câu lệnh try / Catch để tránh sự cố. Tương tự, chỉ cần thực hiện các cuộc gọi kết nối httpURLC kết nối thông thường của bạn, miễn là chúng được xử lý lỗi, bạn sẽ sớm biết liệu mình có kết nối internet hay không
rangi

4

Kotlin và coroutines

Tôi đã đặt chức năng trong một ViewModel, trong đó có viewModelScope. Sử dụng một quan sátLiveData tôi thông báo cho một hoạt động về kết nối.

ViewModel

 fun checkInternetConnection() {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                try {
                    val timeoutMs = 3000
                    val socket = Socket()
                    val socketAddress = InetSocketAddress("8.8.8.8", 53)

                    socket.connect(socketAddress, timeoutMs)
                    socket.close()

                    withContext(Dispatchers.Main) {
                        _connection.value = true
                    }
                }
                catch(ex: IOException) {
                    withContext(Main) {
                        _connection.value = false
                    }
                }
            }
        }
    }
 private val _connection = MutableLiveData<Boolean>()
 val connection: LiveData<Boolean> = _connection

Hoạt động

 private fun checkInternetConnection() {
     viewModel.connection.observe(this) { hasInternet ->
         if(!hasInternet) {
             //hasn't connection
         }
         else {
            //has connection
         }
     }
  }

3

Chỉ cần tạo lớp sau để kiểm tra kết nối internet:

public class ConnectionStatus {

    private Context _context;

    public ConnectionStatus(Context context) {
        this._context = context;
    }

    public boolean isConnectionAvailable() {
        ConnectivityManager connectivity = (ConnectivityManager) _context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null)
                for (int i = 0; i < info.length; i++)
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
        }
        return false;
    }
}

Lớp này chỉ đơn giản chứa một phương thức trả về giá trị boolean của trạng thái kết nối. Do đó, về mặt đơn giản, nếu phương thức tìm thấy kết nối hợp lệ với Internet, thì giá trị trả về là true, nếu không thì falsekhông tìm thấy kết nối hợp lệ.

Phương thức sau trong MainActivity sau đó gọi kết quả từ phương thức được mô tả trước đó và nhắc người dùng hành động tương ứng:

public void addListenerOnWifiButton() {
        Button btnWifi = (Button)findViewById(R.id.btnWifi);

        iia = new ConnectionStatus(getApplicationContext());

        isConnected = iia.isConnectionAvailable();
        if (!isConnected) {
            btnWifi.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
                    Toast.makeText(getBaseContext(), "Please connect to a hotspot",
                            Toast.LENGTH_SHORT).show();
                }
            });
        }
        else {
            btnWifi.setVisibility(4);
            warning.setText("This app may use your mobile data to update events and get their details.");
        }
    }

Trong đoạn mã trên, nếu kết quả là sai, (do đó không có kết nối internet, người dùng sẽ được đưa đến bảng điều khiển wi-fi Android, nơi anh ta được nhắc kết nối với điểm phát sóng wi-fi.


3

Cập nhật 29/06/2015 Nếu bạn đang sử dụng Xamarin.Android và muốn kiểm tra kết nối, bạn có thể sử dụng gói Nuget sẽ cung cấp cho bạn chức năng này trên nhiều nền tảng. Ứng cử viên tốt đang ở đâyở đây . [Kết thúc cập nhật]

Các câu trả lời ở trên khá hay, nhưng tất cả đều bằng Java và hầu hết tất cả chúng đều kiểm tra kết nối. Trong trường hợp của tôi, tôi cần có kết nối với một loại kết nối cụ thể và tôi đang phát triển trên Xamarin.Android. Hơn nữa, tôi không chuyển tham chiếu đến các hoạt động của tôi Bối cảnh trong lớp Phần cứng, tôi sử dụng Bối cảnh ứng dụng. Vì vậy, đây là giải pháp của tôi, trong trường hợp ai đó đến đây với yêu cầu tương tự. Tôi chưa thực hiện kiểm tra đầy đủ, sẽ cập nhật câu trả lời sau khi tôi hoàn thành kiểm tra

using Android.App;
using Android.Content;
using Android.Net;

namespace Leopard.Mobile.Hal.Android
{
    public class AndroidNetworkHelper
    {
        public static AndroidNetworkStatus GetWifiConnectivityStatus()
        {
            return GetConnectivityStatus(ConnectivityType.Wifi);
        }

        public static AndroidNetworkStatus GetMobileConnectivityStatus()
        {
            return GetConnectivityStatus(ConnectivityType.Mobile);
        }

        #region Implementation

        private static AndroidNetworkStatus GetConnectivityStatus(ConnectivityType connectivityType)
        {
            var connectivityManager = (ConnectivityManager)Application.Context.GetSystemService(Context.ConnectivityService);
            var wifiNetworkInfo = connectivityManager.GetNetworkInfo(connectivityType);
            var result = GetNetworkStatus(wifiNetworkInfo);
            return result;
        }

        private static AndroidNetworkStatus GetNetworkStatus(NetworkInfo wifiNetworkInfo)
        {
            var result = AndroidNetworkStatus.Unknown;
            if (wifiNetworkInfo != null)
            {
                if (wifiNetworkInfo.IsAvailable && wifiNetworkInfo.IsConnected)
                {
                    result = AndroidNetworkStatus.Connected;
                }
                else
                {
                    result = AndroidNetworkStatus.Disconnected;
                }
            }
            return result;
        } 

        #endregion
    }

    public enum AndroidNetworkStatus
    {
        Connected,
        Disconnected,
        Unknown
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.