Проверьте, активна ли VPN-связь в Android?


У меня есть стороннее VPN-приложение на моем некорневом устройстве Android 4.4, и я хочу написать фоновую службу для мониторинга VPN-соединения и оповещения пользователя, если VPN-соединение было нарушено.

Есть ли способ сделать это? Я не мог найти никакого способа, используя API VPNService.

Спасибо-D

4 10

4 ответа:

Это работает для меня: Тестировался с API 16 по 23:

  List<String> networkList = new ArrayList<>();
    try {
        for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
            if (networkInterface.isUp())
                networkList.add(networkInterface.getName());
        }
    } catch (Exception ex) {
        Timber.d("isVpnUsing Network List didn't received");
    }

    return networkList.contains("tun0");

P.S. Также это может быть другой networkInterface с именем "ppp0", но в моих тестах с различными VPN-приложениями он всегда был "tun0"

Использование NetworkCapabilities работало на меня. Вы должны обойти все существующие сети и проверить, какая из них имеет VPN_TRANSPORT

ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] networks = cm.getAllNetworks();

Log.i(TAG, "Network count: " + networks.length);
for(int i = 0; i < networks.length; i++) {

  NetworkCapabilities caps = cm.getNetworkCapabilities(networks[i]);

  Log.i(TAG, "Network " + i + ": " + networks[i].toString());
  Log.i(TAG, "VPN transport is: " + caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN));
  Log.i(TAG, "NOT_VPN capability is: " + caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN));

}

Напишите небольшое приложение, которое попадет на внутреннюю страницу или вызовет внутренний сайт...

HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(internal_url);
HttpResponse response = client.execute(request);

String html = "";
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
    str.append(line);
}
in.close();
html = str.toString();

Или

String str = "";
try 
{
    Process process = Runtime.getRuntime().exec(
            "/system/bin/ping -c 8 " + internal_url);
    BufferedReader reader = new BufferedReader(new InputStreamReader(
            process.getInputStream()));
    int i;
    char[] buffer = new char[4096];
    StringBuffer output = new StringBuffer();
    while ((i = reader.read(buffer)) > 0)
        output.append(buffer, 0, i);
    reader.close();


    str = output.toString();

} 
catch (IOException e)
{

    e.printStackTrace();
}
return str;

Как насчет проверки сетевой информации? Если у вас есть тип VPN, я бы предположил, что есть VPN-соединение.

Требуется разрешение ACCESS_NETWORK_STATE.

            List<NetworkInfo> connectedNetworks    = new ArrayList<>();

        if (Build.VERSION.SDK_INT >= 21)
            {
            Network[] networks = m_ConnectivityManager.getAllNetworks();

            for (Network n : networks)
                {
                NetworkInfo ni = m_ConnectivityManager.getNetworkInfo(n);

                if (ni.isConnectedOrConnecting())
                    {
                    connectedNetworks.add(ni);
                    }
                }
            }
        else
            {
            NetworkInfo[] nis = m_ConnectivityManager.getAllNetworkInfo();

            for (NetworkInfo ni : nis)
                {
                if (ni.isConnectedOrConnecting())
                    {
                    connectedNetworks.add(ni);
                    }
                }
            }

        boolean bHasVPN = false;

        if (Build.VERSION.SDK_INT >= 21)
            {
            for (NetworkInfo ni : connectedNetworks)
                {
                bHasVPN |= (ni.getType() == ConnectivityManager.TYPE_VPN);
                }
            }