Intereting Posts
Ручки выбора не отображаются в WebView (Android 4.0-4.3) Изменение сводки CheckBoxPreference на основе проверенного состояния ОШИБКА: Не удалось прочитать ключ из хранилища: … Не удается восстановить ключ в Android Studio при создании подписанного APK Изменение уровня батареи эмулятора в Windows Есть ли ссылка на View.postDelayed для Android? Как предотвратить прокрутку TouchEvent Профайл proguard.cfg отсутствует Почему идентификатор приложения Facebook внезапно стал недействительным? Почему конкретное устройство помечено как «неподдерживаемый» в Google Play Store для Android? Вопросы по шаблону MVP для Android-приложений Запустите приложение Phonegap в определенное время (будильник) Как использовать OpenCV для обработки изображения, чтобы текст стал четким и четким? У Android EditText есть тип ввода с кнопкой очистки? Добавление панели инструментов в FragmentActivity Android ListView mListView.getChildAt (i) null, как его решить?

Ветка зависает на WifiManager.enableNetwork ()

Я вижу, что моя вызывающая строка зависает в собственном коде при вызове WifiManager.enableNetwork (). До сих пор я смог воспроизвести эту повесить на планшете Motorola Xoom под управлением Android 3.2.1. Я тестировал на нескольких других телефонах и планшетах (все они были либо Froyo, либо Gingerbread) и не видели проблемы. Xoom – единственное двухъядерное устройство, которое я должен тестировать (и я воспроизвел проблему на двух разных Xooms), поэтому я чувствую, что я сталкиваюсь с некоторыми очень тонкими требованиями к потоку Android при взаимодействии с WifiManager. Трассировка стека, где висит мой вызывающий поток:

BinderProxy.transact(int, Parcel, Parcel, int) line: not available [native method] IWifiManager$Stub$Proxy.enableNetwork(int, boolean) line: 513 WifiManager.enableNetwork(int, boolean) line: 587 

Мое приложение пытается подключиться к известной точке доступа Wi-Fi, выполнить некоторые тесты, а затем снова подключить устройство к его исходной точке доступа (если оно было ранее подключено). До установления соединения мы уже проверили, что Wi-Fi включен, и мы выполнили проверку, чтобы убедиться, что наш SSID точки доступа найден. Этот код для установления соединения выполняется в AsyncTask и выглядит примерно так:

 ... private WifiManager mWifiManager; private List<WifiConfiguration> mConfiguredNets = new ArrayList<WifiConfiguration>(); private Object mConnectMonitor = new Object(); private NetworkInfo.State mNetworkState = State.UNKNOWN; private final BroadcastReceiver mConnectionStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context inContext, final Intent inIntent) { final String action = inIntent.getAction(); if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { NetworkInfo ni = (NetworkInfo)inIntent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); State state = ni.getState(); if (state == State.CONNECTED) { synchronized (mConnectMonitor) { mNetworkState = state; mConnectMonitor.notify(); } } } } }; public void runninInAsyncTask(Context activityContext, int networkID) { mWifiManager = (WifiManager)activityContext.getSystemService(Context.WIFI_SERVICE); // Register our broadcast receiver to get network state change events IntentFilter ifilter = new IntentFilter(); ifilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); activityContext.registerReceiver(mConnectionStateReceiver, ifilter); // Get a list of our currently configured networks so we can re-enable // them after connecting to the desired network mConfiguredNets = mWifiManager.getConfiguredNetworks(); // Enable our network and disable all others mWifiManager.enableNetwork(networkId, true); // Start the reconnection process to connect to our desired network synchronized (mConnectMonitor) { mWifiManager.reconnect(); mConnectMonitor.wait(60000); if (mNetworkState != State.CONNECTED) { Log.e(TAG, "Problems connecting to desired network!"); } else { Log.e(TAG, "Successfully connected to desired network!"); } } // Re-enable all of our previously configured networks for (WifiConfiguration wifiConfig : mConfiguredNets) { if (wifiConfig.status != Status.ENABLED) { mWifiManager.enableNetwork(wifiConfig.networkId, false); } } } ... 

Этот код был основан на коде меню настроек Wi-Fi в открытом исходном коде Android Gingerbread. Есть ли что-нибудь о вызове WifiManager.enableNetwork (), который мне не хватает? Нужно ли его запускать на определенном потоке? Я попытался убедиться, что enableNetwork () вызывается в потоке пользовательского интерфейса (путем перемещения логики к широковещательному приемнику). Казалось, это немного помогло, но я все еще смог воспроизвести повесить. Может быть, это что-то особенное для Honeycomb? Прямо сейчас эти 2 Xooms являются единственными устройствами Honeycomb, которые я имею для тестирования, поэтому они являются единственными точками данных, которые у меня есть.

г

Это действительно проблема прошивки, характерная для 3. * (кажется).

Я видел, как это произошло на Asus Transformer TF101 и Sony Tablet S (оба с 3. *, что было некоторое время назад).

Начиная с версии 3.0, есть новые API для подключения к Wi-Fi, которые не требуют использования enableNetwork в пакетах (для включения всех сетей, кроме текущего).

Больше о тех API, что я мог бы собрать из исходного кода 4.0:

  • Они отмечены знаком "@hide"
  • Они используются в приложении «Настройки»
  • Они до сих пор не документированы по состоянию на 4.1
  • Они немного изменились между 3. * и 4. * временем выполнения

Моя рекомендация – попытаться использовать эти API через отражение. Поскольку они используются в приложении «Настройки», они работают.