Android S Wi-Fi 打开流程(二)

基于原生的Android S代码: http://aospxref.com/android-13.0.0_r3/
上一篇文章我们记录到:
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
在 IdleState 状态里处理 CMD_START 方法

825          private class IdleState extends State {

844              public boolean processMessage(Message message) {
845                  switch (message.what) {
846                      case CMD_START:
847                          // Always start in scan mode first.
848                          RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
849                          mClientInterfaceName = mWifiNative.setupInterfaceForClientInScanMode(  ---> 继续这个往下看
850                                  mWifiNativeInterfaceCallback, roleChangeInfo.requestorWs);
851                          if (TextUtils.isEmpty(mClientInterfaceName)) {
852                              Log.e(getTag(), "Failed to create ClientInterface. Sit in Idle");
853                              takeBugReportInterfaceFailureIfNeeded(
854                                      "Wi-Fi scan STA interface HAL failure");
855                              mModeListener.onStartFailure(ConcreteClientModeManager.this);
856                              break;
857                          }
858                          if (roleChangeInfo.role instanceof ClientConnectivityRole) {
859                              sendMessage(CMD_SWITCH_TO_CONNECT_MODE, roleChangeInfo);
860                              transitionTo(mStartedState);
861                          } else {
862                              mScanRoleChangeInfoToSetOnTransition = roleChangeInfo;
863                              transitionTo(mScanOnlyModeState);
864                          }
865                          break;
}

/packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java

1263      public String setupInterfaceForClientInScanMode(
1264              @NonNull InterfaceCallback interfaceCallback, @NonNull WorkSource requestorWs) {
1265          synchronized (mLock) {
1266              if (!startHal()) {    ---> 第一点
1267                  Log.e(TAG, "Failed to start Hal");
1268                  mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
1269                  return null;
1270              }
1271              Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_SCAN);
1272              if (iface == null) {
1273                  Log.e(TAG, "Failed to allocate new STA iface");
1274                  return null;
1275              }
1276              iface.externalListener = interfaceCallback;
1277              iface.name = createStaIface(iface, requestorWs);
1278              if (TextUtils.isEmpty(iface.name)) {
1279                  Log.e(TAG, "Failed to create iface in vendor HAL");
1280                  mIfaceMgr.removeIface(iface.id);
1281                  mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
1282                  return null;
1283              }
1284              if (!mWifiCondManager.setupInterfaceForClientMode(iface.name, Runnable::run,  ---> 第二点
1285                      new NormalScanEventCallback(iface.name),
1286                      new PnoScanEventCallback(iface.name))) {
1287                  Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
1288                  teardownInterface(iface.name);
1289                  mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
1290                  return null;
1291              }
1292              iface.networkObserver = new NetworkObserverInternal(iface.id);
1293              if (!registerNetworkObserver(iface.networkObserver)) {   ---> 第三点
1294                  Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
1295                  teardownInterface(iface.name);
1296                  return null;
1297              }
1298              mWifiMonitor.startMonitoring(iface.name);  ---> 第四点比较简单,开始监视传入的iface
1299              // Just to avoid any race conditions with interface state change callbacks,
1300              // update the interface state before we exit.
1301              onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
1302              mWifiVendorHal.enableLinkLayerStats(iface.name);
1303              Log.i(TAG, "Successfully setup " + iface);
1304  
1305              iface.featureSet = getSupportedFeatureSetInternal(iface.name);
1306              return iface.name;
1307          }
1308      }

我们现在来细看下,上面标出的几点代码:
第一点:startHal()

492      /** Helper method invoked to start supplicant if there were no ifaces */
493      private boolean startHal() {
494          synchronized (mLock) {
495              if (!mIfaceMgr.hasAnyIface()) {   ---> 是否有这个接口
496                  if (mWifiVendorHal.isVendorHalSupported()) {  ---> 是否支持HAl
497                      if (!mWifiVendorHal.startVendorHal()) {  ---> 启动 Hal
498                          Log.e(TAG, "Failed to start vendor HAL");
499                          return false;
500                      }
501                      if (SdkLevel.isAtLeastS()) {  ---> 版本大于S执行
502                          mWifiVendorHal.setCoexUnsafeChannels(
503                                  mCachedCoexUnsafeChannels, mCachedCoexRestrictions);
504                      }
505                  } else {
506                      Log.i(TAG, "Vendor Hal not supported, ignoring start.");
507                  }
508              }
509              registerWificondListenerIfNecessary();
510              return true;
511          }
512      }

393       * Bring up the HIDL Vendor HAL.
394       * @return true on success, false otherwise.
395       */
396      public boolean startVendorHal() {
397          synchronized (sLock) {
398              if (!mHalDeviceManager.start()) {   ---> 继续追下去
399                  mLog.err("Failed to start vendor HAL").flush();
400                  return false;
401              }
402              mLog.info("Vendor Hal started successfully").flush();
403              return true;
404          }
405      }

/packages/modules/Wifi/service/java/com/android/server/wifi/HalDeviceManager.java
mHalDeviceManager.start() —> HalDeviceManager. startWifi() 执行:

private boolean startWifi() {
    if (VDBG) Log.d(TAG, "startWifi");
    initIWifiIfNecessary(); // 初始化 IWifi 接口,如果尚未初始化
    synchronized (mLock) {
        try {
            if (mWifi == null) {
                Log.w(TAG, "startWifi called but mWifi is null!?"); 
                return false;
            } else {  // mWifi 不为空,走下面逻辑
                int triedCount = 0;
                while (triedCount <= START_HAL_RETRY_TIMES) {  //可以尝试 3 次
                    WifiStatus status = mWifi.start(); // 调用 mWifi 的 start 方法来启动 Wi-Fi HAL
                    if (status.code == WifiStatusCode.SUCCESS) {
                        initIWifiChipDebugListeners(); // 初始化 IWifiChip 调试监听器
                        managerStatusListenerDispatch(); // 触发管理状态监听器
                        if (triedCount != 0) {
                            Log.d(TAG, "start IWifi succeeded after trying "
                                     + triedCount + " times"); // 如果尝试次数不为 0,则打印成功日志
                        }
                        return true; // 返回启动成功
                    } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
                        // Should retry. Hal might still be stopping.
                        Log.e(TAG, "Cannot start IWifi: " + statusString(status)
                                + ", Retrying..."); // 如果返回的状态是 ERROR_NOT_AVAILABLE,则说明 HAL 可能仍在停止,打印重试日志
                        try {
                            Thread.sleep(START_HAL_RETRY_INTERVAL_MS); // 休眠一段时间后进行重试
                        } catch (InterruptedException ignore) {
                            // no-op
                        }
                        triedCount++;
                    } else {
                        // Should not retry on other failures.
                        Log.e(TAG, "Cannot start IWifi: " + statusString(status)); // 如果返回的状态是其他错误,则打印错误日志
                        return false; 
                    }
                }
                Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times"); 
            }
        } catch (RemoteException e) {
            Log.e(TAG, "startWifi exception: " + e); 
            return false; 
        }
    }
}

继续看下mWifi.start()方法:http://aospxref.com/android-13.0.0_r3/xref/hardware/interfaces/wifi/1.6/default/wifi.cpp#69
Return<void> Wifi::start(start_cb hidl_status_cb) {
    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal, hidl_status_cb);
}

WifiStatus Wifi::startInternal() {
    if (run_state_ == RunState::STARTED) {
        return createWifiStatus(WifiStatusCode::SUCCESS);
    } else if (run_state_ == RunState::STOPPING) {
        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
    }
    WifiStatus wifi_status = initializeModeControllerAndLegacyHal();  ---> 看下这个方法
    if (wifi_status.code == WifiStatusCode::SUCCESS) {
        // Register the callback for subsystem restart
        const auto& on_subsystem_restart_callback = [this](const std::string& error) {
            WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
            for (const auto& callback : event_cb_handler_.getCallbacks()) {
                LOG(INFO) << "Attempting to invoke onSubsystemRestart "
                             "callback";
                if (!callback->onSubsystemRestart(wifi_status).isOk()) {
                    LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
                } else {
                    LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
                                 "callback";
                }
            }
        };

        // Create the chip instance once the HAL is started.
        android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId;
        for (auto& hal : legacy_hals_) {
            chips_.push_back(
                    new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
                                 std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
                                 feature_flags_, on_subsystem_restart_callback));
            chipId++;
        }
        run_state_ = RunState::STARTED;
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onStart().isOk()) {
                LOG(ERROR) << "Failed to invoke onStart callback";
            };
        }
        LOG(INFO) << "Wifi HAL started";
    } else {
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onFailure(wifi_status).isOk()) {
                LOG(ERROR) << "Failed to invoke onFailure callback";
            }
        }
        LOG(ERROR) << "Wifi HAL start failed";
        // Clear the event callback objects since the HAL start failed.
        event_cb_handler_.invalidate();
    }
    return wifi_status;
}

WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
    if (!mode_controller_->initialize()) {  ---> 这里的mode_controller 指的是WifiModeController,所以到这个类看下初始化方法
        LOG(ERROR) << "Failed to initialize firmware mode controller";
        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    }

    legacy_hals_ = legacy_hal_factory_->getHals();
    if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    int index = 0;  // for failure log
    for (auto& hal : legacy_hals_) {
        legacy_hal::wifi_error legacy_status = hal->initialize();
        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
            // Currently WifiLegacyHal::initialize does not allocate extra mem,
            // only initializes the function table. If this changes, need to
            // implement WifiLegacyHal::deinitialize and deinitalize the
            // HALs already initialized
            LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
                       << " error: " << legacyErrorToString(legacy_status);
            return createWifiStatusFromLegacyError(legacy_status);
        }
        index++;
    }
    return createWifiStatus(WifiStatusCode::SUCCESS);
}
http://aospxref.com/android-13.0.0_r3/xref/hardware/interfaces/wifi/1.6/default/wifi_mode_controller.cpp
bool WifiModeController::initialize() {
    if (!driver_tool_->LoadDriver()) {  ---> 这个就是我们熟知的去加载驱动操作了
        LOG(ERROR) << "Failed to load WiFi driver";
        return false;
    }
    return true;
}
// driver_tool_定义的地方
#include <wifi_hal/driver_tool.h>
std::unique_ptr<wifi_hal::DriverTool> driver_tool_;
WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
全集搜索下,可以发现位置在:
http://aospxref.com/android-13.0.0_r3/xref/frameworks/opt/net/wifi/libwifi_hal/include/wifi_hal/driver_tool.h
再找到对的LoadDriver:http://aospxref.com/android-13.0.0_r3/xref/frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp#34
bool DriverTool::LoadDriver() {
  return ::wifi_load_driver() == 0;
}

http://aospxref.com/android-13.0.0_r3/xref/frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp?fi=wifi_load_driver#wifi_load_driver

int wifi_load_driver() {
#ifdef WIFI_DRIVER_MODULE_PATH
  if (is_wifi_driver_loaded()) {
    return 0;
  }
  if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1;
#endif

#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
  if (is_wifi_driver_loaded()) {
    return 0;
  }
  if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) {
#ifdef WIFI_DRIVER_MODULE_PATH
    PLOG(WARNING) << "Driver unloading, err='fail to change driver state'";
    if (rmmod(DRIVER_MODULE_NAME) == 0) {
      PLOG(DEBUG) << "Driver unloaded";
    } else {
      // Set driver prop to "ok", expect HL to restart Wi-Fi.
      PLOG(DEBUG) << "Driver unload failed! set driver prop to 'ok'.";
      property_set(DRIVER_PROP_NAME, "ok");
    }
#endif
    return -1;
  }
#endif
  is_driver_loaded = true;
  return 0;
}

int is_wifi_driver_loaded() {
  char driver_status[PROPERTY_VALUE_MAX];
#ifdef WIFI_DRIVER_MODULE_PATH
  FILE *proc;
  char line[sizeof(DRIVER_MODULE_TAG) + 10];
#endif

  if (!property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
    return 0; /* driver not loaded */
  }

  if (!is_driver_loaded) {
    return 0;
  } /* driver not loaded */

#ifdef WIFI_DRIVER_MODULE_PATH
  /*
   * If the property says the driver is loaded, check to
   * make sure that the property setting isn't just left
   * over from a previous manual shutdown or a runtime
   * crash.
   */
  if ((proc = fopen(MODULE_FILE, "r")) == NULL) {
    PLOG(WARNING) << "Could not open " << MODULE_FILE;
    is_driver_loaded = false;
    if (strcmp(driver_status, "unloaded") != 0) {
      property_set(DRIVER_PROP_NAME, "unloaded");
    }
    return 0;
  }
  while ((fgets(line, sizeof(line), proc)) != NULL) {
    if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) {
      fclose(proc);
      return 1;
    }
  }
  fclose(proc);
  is_driver_loaded = false;
  if (strcmp(driver_status, "unloaded") != 0) {
    property_set(DRIVER_PROP_NAME, "unloaded");
  }
  return 0;
#else
  return 1;
#endif
}

第二点:mWifiCondManager.setupInterfaceForClientMode 接口

public boolean setupInterfaceForClientMode(@NonNull String ifaceName,
        @NonNull @CallbackExecutor Executor executor,
        @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) {
    Log.d(TAG, "Setting up interface for client mode"); // 设置客户端模式

    if (!retrieveWificondAndRegisterForDeath()) {
        return false; // 如果无法获取 wificond 并注册死亡监听,则返回失败
    }

    if (scanCallback == null || pnoScanCallback == null || executor == null) {
        Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks");
        return false; // 如果回调为 null,则返回失败
    }

    IClientInterface clientInterface = null;
    try {
        clientInterface = mWificond.createClientInterface(ifaceName); // 创建客户端接口,注意这个是IWificond mWificond
    } catch (RemoteException e1) {
        Log.e(TAG, "Failed to get IClientInterface due to remote exception");
        return false; // 如果出现远程异常,则返回失败
    }

    if (clientInterface == null) {
        Log.e(TAG, "Could not get IClientInterface instance from wificond");
        return false; // 如果获取到的客户端接口为 null,则返回失败
    }
    Binder.allowBlocking(clientInterface.asBinder()); // 允许阻塞调用客户端接口的方法

    // Refresh Handlers
    mClientInterfaces.put(ifaceName, clientInterface); // 将客户端接口添加到接口列表中
    try {
        IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); // 获取 WifiScannerImpl
        if (wificondScanner == null) {
            Log.e(TAG, "Failed to get WificondScannerImpl");
            return false; // 如果获取到的 WifiScannerImpl 为 null,则返回失败
        }
        mWificondScanners.put(ifaceName, wificondScanner); // 将 WifiScannerImpl 添加到扫描器列表中
        Binder.allowBlocking(wificondScanner.asBinder()); // 允许阻塞调用 WifiScannerImpl 的方法
        ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback); // 创建扫描事件处理程序
        mScanEventHandlers.put(ifaceName,  scanEventHandler); // 将扫描事件处理程序添加到处理程序列表中
        wificondScanner.subscribeScanEvents(scanEventHandler); // 订阅扫描事件
        PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor,
                pnoScanCallback); // 创建 PNO 扫描事件处理程序
        mPnoScanEventHandlers.put(ifaceName,  pnoScanEventHandler); // 将 PNO 扫描事件处理程序添加到处理程序列表中
        wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); // 订阅 PNO 扫描事件
    } catch (RemoteException e) {
        Log.e(TAG, "Failed to refresh wificond scanner due to remote exception");
    }
    return true; // 返回成功
}

第三点:registerNetworkObserver(iface.networkObserver)

private boolean registerNetworkObserver(NetworkObserverInternal observer) {
    if (observer == null) return false; // 如果观察者为 null,则返回失败
    mNetdWrapper.registerObserver(observer); // 注册网络观察者,mNetdWrapper是网络服务的封装类
    return true;
}

上面我们已经大致看完了,总结下:

  1. 启动HAl层,然后去加载驱动
  2. 通过和/system/connectivity/wificond/里面的Service建立关系,为了后续扫描作准备
  3. 注册网络观察者

小伙伴有没有疑惑?为啥没有启动wpa_supplicant呢,这个可以负责整个Wi-Fi连接、认证、加密等等重要的步骤,说到这,我们就要知道自从Android P开始,扫描这块就逐渐的从wpa_supplicant中给剥离了,由 IWificond 去负责,所以我们在WifiNative.setupInterfaceForClientInScanMode模式中并没有看到这个初始化步骤,那我们既然是梳理打开Wi-Fi的流程,怎么可能只是ClientScanMode模式呢,肯定是要切换到连接的mode。再回到当初最开始ConcreteClientModeManager类中,StartedState状态处理CMD_SWITCH_TO_CONNECT_MODE消息的时候,没有印象的看我之前记录的这篇:Android S Wi-Fi 打开流程(一)
其中有这样一句代码:mWifiNative.switchClientInterfaceToConnectivityMode
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java#1436

    public boolean switchClientInterfaceToConnectivityMode(@NonNull String ifaceName, @NonNull WorkSource requestorWs) {
        synchronized (mLock) {
            final Iface iface = mIfaceMgr.getIface(ifaceName);
            if (iface == null) {
                Log.e(TAG, "Trying to switch to connectivity mode on an invalid iface=" + ifaceName);
                return false;
            }
            //应为此时setupInterfaceForClientInScanMode所分配的iface.type是IFACE_TYPE_STA_FOR_SCAN
            //并不是IFACE_TYPE_STA_FOR_CONNECTIVITY,所以这个if不满足
            if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY) {
                Log.e(TAG, "Already in connectivity mode on iface=" + ifaceName);
                return true;
            }
            //至此,上面setupInterfaceForClientInScanMode都初始化过了
            if (mWifiVendorHal.isVendorHalSupported()
                    && !mWifiVendorHal.replaceStaIfaceRequestorWs(iface.name, requestorWs)) {
                Log.e(TAG, "Failed to replace requestor ws on " + iface);
                teardownInterface(iface.name);
                return false;
            }
            //判断wpa_supplicant是否启动,没有则初始化
            if (!startSupplicant()) {
                Log.e(TAG, "Failed to start supplicant");
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            }
            //设置接口名和名称对应
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            }
            if (mContext.getResources().getBoolean( R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled)) {
                if (!mSupplicantStaIfaceHal.setNetworkCentricQosPolicyFeatureEnabled(iface.name, true)) {
                    Log.e(TAG, "Failed to set QoS policy feature enabled for iface " + iface.name);
                    return false;
                }
            }
            iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
            //获取支持的能力,比如加密方式、新特性等等
            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            saveCompleteFeatureSetInConfigStoreIfNecessary(iface.featureSet);
            mIsEnhancedOpenSupported = (iface.featureSet & WIFI_FEATURE_OWE) != 0;
            Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
            return true;
        }
    }

现在我们就知道了,原来在这里将启动wpa_supplicant,至此,整个Wi-Fi打开的大致流程就到此梳理完毕,细节的多看下代码即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于 Android Wi-Fi 直连传输数据的实践,可以使用 AndroidWi-Fi P2P(Wi-Fi Direct)功能来实现。下面是一个简单的示例代码,演示了如何在两台设备之间进行 Wi-Fi 直连传输数据: 首先,在 AndroidManifest.xml 文件中添加以下权限: ```xml <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> ``` 然后,在你的 Activity 中添加以下代码: ```java private WifiP2pManager mManager; private WifiP2pManager.Channel mChannel; private BroadcastReceiver mReceiver; private IntentFilter mIntentFilter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化 Wi-Fi P2P 相关对象 mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(this, getMainLooper(), null); // 注册广播接收器,用于接收 Wi-Fi P2P 相关的系统广播 mReceiver = new WiFiDirectBroadcastReceiver(); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); } @Override protected void onResume() { super.onResume(); registerReceiver(mReceiver, mIntentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mReceiver); } // 开始 Wi-Fi P2P 搜索设备 public void discoverPeers(View view) { mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // 搜索成功 } @Override public void onFailure(int reasonCode) { // 搜索失败 } }); } // 连接到指定设备 public void connectToDevice(WifiP2pDevice device) { WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // 连接成功 } @Override public void onFailure(int reason) { // 连接失败 } }); } // 发送数据 public void sendData(byte[] data) { // 通过 Socket 发送数据 // 这里省略具体实现代码 } // 接收数据 public void receiveData(byte[] data) { // 通过 Socket 接收数据 // 这里省略具体实现代码 } // 广播接收器,用于接收 Wi-Fi P2P 相关的系统广播 private class WiFiDirectBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { // Wi-Fi P2P 状态变化 } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // 可用的对等设备列表发生变化 } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { // Wi-Fi P2P 连接状态发生变化 } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { // 本设备的信息发生变化 } } } ``` 以上是一个简单的 Android Wi-Fi 直连传输数据的实践示例,其中涉及到了 Wi-Fi P2P 的搜索设备、连接设备以及发送和接收数据的过程。需要注意的是,具体的发送和接收数据的实现需要借助 Socket 或其他网络通信方式来完成,这里只是一个简单的示例。 希望对您有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值