English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

AndroidのWifiのforget()操作の詳細な例

Android  Wifi的forget()操作实例详解

我们在处理某个Wifi连接时,有时会需要忘掉当前连接的密码信息。执行这项操作,我们需要调用WifiManager::forget()函数:

/** 
 * Delete the network in the supplicant config. 
 * 
 * This function is used instead of a sequence of removeNetwork() 
 * and saveConfiguration(). 
 * 
 * @param config the set of variables that describe the configuration, 
 *      contained in a {@link WifiConfiguration} object. 
 * @param listener for callbacks on success or failure. Can be null. 
 * @throws IllegalStateException if the WifiManager instance needs to be 
 * initialized again 
 * @hide 
 */ 
public void forget(int netId, ActionListener listener) { 
  if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 
  validateChannel(); 
  sAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener)); 
} 

関数の説明から、forget()関数を呼び出すと、現在のネットワーク接続の設定情報がwpa_supplicant.confから削除されます;その後、このネットワークには自動再接続の動作がなくなるため、confファイルにはこのネットワークの設定情報がありません。

FORGET_NETWORKメッセージを追跡し、WifiServiceImpl::ClientHandlerが処理します:

case WifiManager.FORGET_NETWORK: 
  if (isOwner(msg.sendingUid)) { 
    mWifiStateMachine.sendMessage(Message.obtain(msg)); 
  } else { 
    Slog.e(TAG, "ユーザーに対してForgetが認可されていません"); 
    replyFailed(msg, WifiManager.FORGET_NETWORK_FAILED, 
        WifiManager.NOT_AUTHORIZED); 
  } 
  break; 

このメッセージをWi-Fiステートマシンに単純に転送します。この時、Wi-Fiは接続状態で、Wi-Fiステートマシンの現在の状態はConnectedStateで、親状態のConnectModeStateが処理します:

case WifiManager.FORGET_NETWORK: 
  // デバッグ専用、忘れた最後の設定を覚えとる 
  WifiConfiguration toRemove 
      = mWifiConfigStore.getWifiConfiguration(message.arg1); 
  if (toRemove == null) { 
    lastForgetConfigurationAttempt = null; 
  } else { 
    lastForgetConfigurationAttempt = new WifiConfiguration(toRemove); 
  } 
  // check that the caller owns this network 
  netId = message.arg1; 
  if (!mWifiConfigStore.canModifyNetwork(message.sendingUid, netId, 
      /* onlyAnnotate */ false)) { 
    logw("Not authorized to forget network " 
       + " cnid=" + netId 
       + " uid=" + message.sendingUid); 
    replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED, 
        WifiManager.NOT_AUTHORIZED); 
    break; 
  } 
  if (mWifiConfigStore.forgetNetwork(message.arg1)) { 
    replyToMessage(message, WifiManager.FORGET_NETWORK_SUCCEEDED); 
    broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_FORGOT, 
        (WifiConfiguration) message.obj); 
  } else { 
    loge("Failed to forget network"); 
    replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED, 
        WifiManager.ERROR); 
  } 
  break; 

mWifiConfigStore.forgetNetwork():

/** 
 * Forget the specified network and save config 
 * 
 * @param netId network to forget 
 * @return {@code true} if it succeeds, {@code false} otherwise 
 */ 
boolean forgetNetwork(int netId) { 
  if (showNetworks) localLog("forgetNetwork", netId); 
  WifiConfiguration config = mConfiguredNetworks.get(netId); 
  boolean remove = removeConfigAndSendBroadcastIfNeeded(netId); 
  if (!remove) { 
    //成功しましたが、 supplicant conf ファイルからネットワークを削除する必要はありません 
    return true; 
  } 
  if (mWifiNative.removeNetwork(netId)) { 
    if (config != null && config.isPasspoint()) { 
      writePasspointConfigs(config.FQDN, null); 
    } 
    mWifiNative.saveConfig(); 
    writeKnownNetworkHistory(true); 
    return true; 
  } else { 
    loge("ネットワーク削除に失敗しました " + netId); 
    return false; 
  } 
} 

現在のネットワークのnetIdに基づいて、WifiNativeのremoveNetwork()、saveConfig()メソッドを呼び出し、confファイルの設定情報を削除し保存します。実行が完了すると、forget()関数が終了します。コードから見て、forget()関数の実行はWifiStateMachineの状態の切り替えを引き起こしません。

ご読阅ありがとうございます。皆様のサポートに感謝します!

声明:この記事の内容はインターネットから取得しており、著作権者に帰属します。インターネットユーザーが自発的に貢献し、アップロードしたものであり、このサイトは所有権を有しておらず、編集されていません。著作権侵害が疑われる内容がある場合は、メールで:notice#w までお知らせください。3codebox.com(メールを送信する際は、#を@に変更してください)で通報し、関連する証拠を提供してください。一旦確認がとりついたら、このサイトは即座に侵害されている内容を削除します。

おすすめ