Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธี Ping IP/Host ภายนอกใน Android (Java)

บทความนี้สาธิตวิธีตรวจสอบการเชื่อมต่อเครือข่ายและ Ping ไปยัง IP/Host ภายนอก ใน Android โดยใช้ Runtime.exec() รันคำสั่ง ping ของระบบ

⚠️ ข้อจำกัดและข้อควรระวัง

  • Runtime.exec("ping ...") ขึ้นอยู่กับระบบปฏิบัติการ - อาจไม่ทำงานบนบางอุปกรณ์/ROM
  • Android 7.0+ (API 24+) จำกัดการ exec คำสั่งระบบ (SELinux)
  • ไม่แนะนำ สำหรับ Production App - ควรใช้ HTTP Request หรือ ICMP Library แทน
  • ต้องการสิทธิ์ INTERNET และ ACCESS_NETWORK_STATE

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → File → New Project

ขั้นตอนที่ 2: Layout (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Network Connectivity Test"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

ขั้นตอนที่ 3: MainActivity.java

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        checkNetworkAndPing();
    }

    private void checkNetworkAndPing() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();

        boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        boolean isWiFi = activeNetwork != null && activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
        boolean isMobile = activeNetwork != null && activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE;

        if (!isConnected) {
            Toast.makeText(this, "No Network Connection", Toast.LENGTH_SHORT).show();
            return;
        }

        String networkType = isWiFi ? "WiFi" : (isMobile ? "Mobile Data" : "Other");
        Toast.makeText(this, "Connected via: " + networkType, Toast.LENGTH_SHORT).show();

        // Ping ทดสอบ
        String host = "8.8.8.8"; // Google DNS
        if (pingHost(host)) {
            Toast.makeText(this, "Ping to " + host + " SUCCESS", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Ping to " + host + " FAILED", Toast.LENGTH_LONG).show();
        }
    }

    private boolean pingHost(String host) {
        Runtime runtime = Runtime.getRuntime();
        try {
            // -c 1 = ส่ง 1 packet, -w 5 = timeout 5 วินาที
            String command = "/system/bin/ping -c 1 -w 5 " + host;
            Process process = runtime.exec(command);
            int exitValue = process.waitFor();
            return exitValue == 0;
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }
}

ขั้นตอนที่ 4: AndroidManifest.xml

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

วิธีที่ดีกว่า: ใช้ HTTP/HTTPS Request (แนะนำ Production)

แทน Ping ให้เรียก HTTP Request ไปยัง Endpoint ที่น่าเชื่อถือ:

// ใช้ OkHttp (แนะนำ)
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
        .url("https://www.google.com/generate_204") // Google connectivity check endpoint
        .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // Network error
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.code() == 204) {
            // Connected
        }
    }
});

วิธีอื่น: InetAddress.isReachable (ไม่แนะนำ)

InetAddress address = InetAddress.getByName("8.8.8.8");
boolean reachable = address.isReachable(5000); // 5 sec timeout
// ปัญหา: บน Android มักคืนค่า false เสมอเนื่องจาก ICMP ถูกบล็อก

Network Callback (Android 5.0+ / API 21+) - Best Practice

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest request = new NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .build();

cm.registerNetworkCallback(request, new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        // มีอินเทอร์เน็ต
    }
    @Override
    public void onLost(Network network) {
        // ขาดการเชื่อมต่อ
    }
});

สรุป

  • Ping (Runtime.exec) - ใช้ได้สำหรับทดสอบ/เรียนรู้ แต่ไม่เชื่อถือได้ Production
  • HTTP Request (OkHttp/Retrofit) - แนะนำสำหรับ Production จริง
  • NetworkCallback - ติดตามสถานะเครือข่าย Real-time (Best Practice)