Как проверить, подключены ли Google Glass к Интернету с помощью GDK

Есть ли способ определить, подключены ли Google Glass к Интернету во время работы? Например, я часто получаю сообщение «Не удается связаться с Google прямо сейчас» при использовании голосового ввода в моем приложении. Вместо этого я хотел бы предварительно перехватить условие, которое вызовет это сообщение, и использовать значения по умолчанию, а не запрашивать голосовой ввод. После некоторого поиска единственное, что я смог найти, это решение того же вопроса для Android в целом:

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

Я пытался использовать это для своего Glassware, но, похоже, это не работает (я отключил Wi-Fi и передачу данных, но isConnected() по-прежнему возвращает значение true, хотя я получаю сообщение «Не удается связаться с Google прямо сейчас»). Кто-нибудь знает, есть ли у GDK способ сделать это? Или должно работать что-то похожее на описанный выше метод?

EDIT: вот мое окончательное решение, частично основанное на ответе EntryLevelDev ниже.

Мне пришлось использовать фоновый поток для использования запросов HTTP GET, чтобы избежать исключения NetworkOnMainThreadException, поэтому я решил запускать его каждые несколько секунд и обновлять локальную переменную isConnected:

public static boolean isConnected = false;

public boolean isDeviceConnectedToInternet() {
    return isConnected;
}

private class CheckConnectivityTask extends AsyncTask<Void, Boolean, Boolean> {
    protected Boolean doInBackground(Void... voids) {
        while(true) {
            // Update isConnected variable.
            publishProgress(isConnected());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Determines if the Glassware can access the internet.
     * isNetworkAvailable() is used first because there is no point in executing an HTTP GET
     * request if ConnectivityManager and NetworkInfo tell us that no network is available.
     */
    private boolean isConnected(){
        if (isNetworkAvailable()) {
            HttpGet httpGet = new HttpGet("http://www.google.com");
            HttpParams httpParameters = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(httpParameters, 3000);
            HttpConnectionParams.setSoTimeout(httpParameters, 5000);

            DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
            try{
                Log.d(LOG_TAG, "Checking network connection...");
                httpClient.execute(httpGet);
                Log.d(LOG_TAG, "Connection OK");
                return true;
            }
            catch(ClientProtocolException e){
                e.printStackTrace();
            }
            catch(IOException e){
                e.printStackTrace();
            }
            Log.d(LOG_TAG, "Connection unavailable");
        } else {
            // No connection; for Glass this probably means Bluetooth is disconnected.
            Log.d(LOG_TAG, "No network available!");
        }
        return false;
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        Log.d(LOG_TAG, String.format("In isConnected(), activeNetworkInfo.toString(): %s",
                activeNetworkInfo == null ? "null" : activeNetworkInfo.toString()));
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    protected void onProgressUpdate(Boolean... isConnected) {
        DecisionMakerService.isConnected = isConnected[0];
        Log.d(LOG_TAG, "Checking connection: connected = " + isConnected[0]);
    }
}

Чтобы запустить его, вызовите new CheckConnectivityTask().execute(); (вероятно, из onCreate()). Мне также пришлось добавить их в свой Android.manifest:

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

person Tony Wickham    schedule 30.12.2013    source источник
comment
Это не работает? Странный...   -  person MCKapur    schedule 30.12.2013
comment
Я думаю, что это должно работать, но есть ошибка, как предложил Тони Аллевато. Пока я попробую ответ EntryLevelDev, хотя он кажется немного менее оптимальным.   -  person Tony Wickham    schedule 02.01.2014


Ответы (2)


Если Glass подключается к телефону с помощью Bluetooth, ваш метод возвращает значение true, даже если ваш телефон не имеет Wi-Fi и подключения для передачи данных.

Думаю, это правильное поведение. getActiveNetworkInfo больше относится к подключению через доступные интерфейсы. Дело не в подключении к интернету. Это похоже на то, что подключение к маршрутизатору не означает, что вы подключаетесь к Интернету.

ПРИМЕЧАНИЕ (из документа):

getActiveNetworkInfo возвращает

объект NetworkInfo для текущей сети по умолчанию или нуль, если сеть по умолчанию в настоящее время не активна

Чтобы проверить подключение к Интернету, вы можете вместо этого попробовать пропинговать Google, хотя я думаю, что может быть лучший способ проверить.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    new Thread(new Runnable() {

        @Override
        public void run() {
            Log.v(MainActivity.class.getSimpleName(), "isGoogleReachable : "
                    + isGoogleReachable());
        }
        
    }).start();;
    
}
private boolean isGoogleReachable() {
    try {
        if (InetAddress.getByName("www.google.com").isReachable(5000)) {
            return true;
        } else {
            return false;
        }
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return false;
    }
}

Добавьте это разрешение:

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

EDIT: Или вы можете попробовать это:

public static void isNetworkAvailable(Context context){
    HttpGet httpGet = new HttpGet("http://www.google.com");
    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    // The default value is zero, that means the timeout is not used.
    int timeoutConnection = 3000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT)
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 5000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

    DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
    try{
        Log.d(TAG, "Checking network connection...");
        httpClient.execute(httpGet);
        Log.d(TAG, "Connection OK");
        return;
    }
    catch(ClientProtocolException e){
        e.printStackTrace();
    }
    catch(IOException e){
        e.printStackTrace();
    }

    Log.d(TAG, "Connection unavailable");
}

См. также:

Определить, подключено ли устройство Android к Интернету

должно ли работать что-то похожее на описанный выше метод?

Да, работает нормально, если еще и Bluetooth выключен.

person pt2121    schedule 30.12.2013
comment
Первый вариант мне не всегда подходит! (Используя InetAddress.getByName....). Иногда я получаю, что isResearchable верен, но я просто отключил Wi-Fi на мобильном телефоне. Второй вариант работает для меня хорошо! Но я полагал, что Google даст нам решение для этого (эта проблема принята в системе отслеживания проблем). - person Bae; 08.05.2014

Когда у вас отключен Wi-Fi и данные, какое имя типа сети возвращает activeNetworkInfo.getTypeName()?

Это может быть ошибка. Вы можете выгрузить как можно больше информации из объекта NetworkInfo (особенно имя типа, перечисление DetailedState и т. д.) и сохранить ее в нашем система отслеживания ошибок?

person Tony Allevato    schedule 30.12.2013
comment
Хорошо, я логировал сообщения об activeNetworkInfo в двух случаях: в первом мой телефон был подключен к данным (но не к WiFi), а во втором он вообще не был подключен к интернету. В обоих случаях мой Glass был подключен к телефону через Bluetooth. Как ни странно, мои сообщения в журнале оба раза были одинаковыми! Оба раза activeNetworkInfo.getTypeName() возвращал COMPANION_PROXY, а DetailedState был CONNECTED. Я отправлю более подробную информацию в трекер проблем. (Кстати, как упомянул EntryLevelDev в своем ответе, мой метод isConnected() правильно возвращает false, когда Bluetooth выключен.) - person Tony Wickham; 02.01.2014