Android Wifi IP 设置

该博客主要围绕Android开发中的Wi-Fi功能展开。代码实现了Wi-Fi扫描、配置保存等功能,包含创建Wi-Fi活动、注册广播接收器、显示编辑对话框等操作,还涉及异常处理,如输入错误时给出提示。
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

public class WifiActivity extends Activity implements OnClickListener{
	protected static final String TAG = "WifiActivity";
	
	public final static String KEY_WIFI_PRIORITY = "wifi_priority";
	public final static String KEY_WIFI_STATIC_IP = "wifi_static_ip";
	
	WifiP2pManager mManager;
	Channel mChannel;
	BroadcastReceiver mReceiver;
	IntentFilter mIntentFilter;
	private WifiManager mWifiManager;
	private List<ScanResult> mListResult;
	private WifiAdapter mWifiAdapter;
	private ListView mList;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
        setContentView(R.layout.wifi_list);
        ImageButton btn = (ImageButton)findViewById(R.id.back);
        btn.setOnClickListener(this);
        mList = (ListView)findViewById(R.id.list_view);
        mReceiver = new WifiReceiver(new WifiScanListener() {
			
			@Override
			public void suppStateChange() {
				
			}
			
			@Override
			public void stateChange() {
				
			}
			
			@Override
			public void endScan() {
				endScanWifi(mWifiManager.getScanResults());				
			}
		});
        
        mIntentFilter = new IntentFilter();
        
        mIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
        mIntentFilter.addAction("android.net.wifi.SCAN_RESULTS");
        mIntentFilter.addAction("android.net.wifi.supplicant.STATE_CHANGE");
        
        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);        
        mWifiManager.setWifiEnabled(true);
        mWifiAdapter = new WifiAdapter(this, null);
        mList.setAdapter(mWifiAdapter);
        
    }
    
//    void showLog(String msg) {
//		new AlertDialog.Builder(this).setTitle(R.string.alert_dialog_prompt).setMessage(msg).show();
//	}

	void promptMessage(String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
	}
    
    public void showEditWifi(final ScanResult sr){
    	LayoutInflater factory = LayoutInflater.from(this);
		final View textEntryView = factory.inflate(R.layout.dialog_wifi_setting, null);
		new AlertDialog.Builder(this).setIconAttribute(android.R.attr.dialogIcon).setTitle(sr.SSID).setView(textEntryView).setCancelable(false)
				.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						try {
							EditText edtWifiPwd = (EditText) textEntryView.findViewById(R.id.edt_wifi_pwd);
							EditText edtStaticIp = (EditText) textEntryView.findViewById(R.id.edt_static_ip);
							EditText edtStaticGateway = (EditText) textEntryView.findViewById(R.id.edt_static_gateway);
							EditText edtStaticNetmask = (EditText) textEntryView.findViewById(R.id.edt_static_netmask);
							EditText edtStaticDns = (EditText) textEntryView.findViewById(R.id.edt_static_dns);
							
							String wifiPwd = edtWifiPwd.getText().toString().trim();
							String ip = edtStaticIp.getText().toString().trim();
							String gateway = edtStaticGateway.getText().toString().trim();
							String prefixLength = edtStaticNetmask.getText().toString().trim();
							String dns = edtStaticDns.getText().toString().trim();
							
							saveStaticWifiConfig(sr,wifiPwd,ip,Integer.parseInt(prefixLength));
						}catch (IllegalArgumentException e) {
							promptMessage(getString(R.string.system_wifi_ip_error));
						} catch (Exception e) {
							e.printStackTrace();
							promptMessage(getString(R.string.system_wifi_setting_error));
						}
					}
				}).setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						dialog.cancel();
					}
				}).create().show();
		
		try {
			WifiConfiguration historyWifiConfig = getHistoryWifiConfig(sr.SSID);
			EditText edtWifiPwd = (EditText) textEntryView.findViewById(R.id.edt_wifi_pwd);
			EditText edtStaticIp = (EditText) textEntryView.findViewById(R.id.edt_static_ip);
			EditText edtStaticGateway = (EditText) textEntryView.findViewById(R.id.edt_static_gateway);
			EditText edtStaticNetmask = (EditText) textEntryView.findViewById(R.id.edt_static_netmask);
			EditText edtStaticDns = (EditText) textEntryView.findViewById(R.id.edt_static_dns);
			
	    	if(historyWifiConfig != null){    		
	    		InetAddress address = getIpAddress(historyWifiConfig);
	    		if(address != null){
	    			edtStaticIp.setText(address.getHostAddress());
	    			address = null;
	    		}
	    		address = getGateway(historyWifiConfig);
	    		if(address != null){
	    			edtStaticGateway.setText(address.getHostAddress());
	    			address = null;
	    		}
	    		address = getDNS(historyWifiConfig);
	    		if(address != null){
	    			edtStaticDns.setText(address.getHostAddress());
	    			address = null;
	    		}
	    		edtStaticNetmask.setText(getNetworkPrefixLength(historyWifiConfig));			
				
	    	}
	    	
	    	if(TextUtils.isEmpty(edtStaticIp.getText().toString().trim())){
	    		String ipString = SmartHomePreference.getStringProperty(KEY_WIFI_STATIC_IP);
	    		int intIp = inetAddressToInt(InetAddress.getByName(ipString)); 
	    		String dns = (intIp & 0xFF ) + "." + ((intIp >> 8 ) & 0xFF) + "." + ((intIp >> 16 ) & 0xFF) + ".1";
	    		
	    		edtStaticIp.setText(ipString);
	    		edtStaticNetmask.setText("24");
	    		edtStaticGateway.setText(dns);
	    		edtStaticDns.setText(dns);	    		
	    	}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
    }
    
    /**
     * 设置wifi,编辑静态IP
     * @param sr
     * @param pwd
     * @param ip
     * @throws Exception
     */
    public void saveStaticWifiConfig(final ScanResult sr,String pwd, String ip,int networkPrefixLength) throws Exception{  
    	InetAddress intetAddress  = InetAddress.getByName(ip);
    	int intIp = inetAddressToInt(intetAddress);    	
    	WifiConfiguration historyWifiConfig = getHistoryWifiConfig(sr.SSID);        	
    	if(historyWifiConfig == null){
    		historyWifiConfig = createComWifiConfig(sr.SSID,pwd);    		
    	}else{
    		if(!TextUtils.isEmpty(pwd)){
    			historyWifiConfig.preSharedKey = "\""+ pwd + "\"";  
    		}
    	}
    	
    	String dns = (intIp & 0xFF ) + "." + ((intIp >> 8 ) & 0xFF) + "." + ((intIp >> 16 ) & 0xFF) + ".1";
    	setIpAssignment("STATIC", historyWifiConfig); //"STATIC" or "DHCP" for dynamic setting
        setIpAddress(intetAddress, networkPrefixLength, historyWifiConfig);
        setGateway(InetAddress.getByName(dns), historyWifiConfig);
        setDNS(InetAddress.getByName(dns), historyWifiConfig);          
        
        mWifiManager.removeNetwork(historyWifiConfig.networkId);
        int netId = mWifiManager.addNetwork(historyWifiConfig);
		mWifiManager.enableNetwork(netId, true);
        mWifiManager.updateNetwork(historyWifiConfig); //apply the setting
        SmartHomePreference.setProperty(WifiActivity.KEY_WIFI_PRIORITY, sr.SSID);
        
        mWifiManager.startScan();
	}
    
    
    /***
     * Convert a IPv4 address from an InetAddress to an integer
     * @param inetAddr is an InetAddress corresponding to the IPv4 address
     * @return the IP address as an integer in network byte order
     */
    public static int inetAddressToInt(InetAddress inetAddr)
            throws IllegalArgumentException {
        byte [] addr = inetAddr.getAddress();
        if (addr.length != 4) {
            throw new IllegalArgumentException("Not an IPv4 address");
        }
        return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
                ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
    }
    
    public void editStaticWifiConfig(final ScanResult sr,String pwd, String ip, String gateway,int prefixLength,String dns) throws Exception{        
    	WifiConfiguration historyWifiConfig = getHistoryWifiConfig(sr.SSID);
    	
    	if(historyWifiConfig == null){
    		historyWifiConfig = createComWifiConfig(sr.SSID,pwd);
    		int netId = mWifiManager.addNetwork(historyWifiConfig);
    		mWifiManager.enableNetwork(netId, true);
    	}
    	
        setIpAssignment("STATIC", historyWifiConfig); //"STATIC" or "DHCP" for dynamic setting
        setIpAddress(InetAddress.getByName(ip), prefixLength, historyWifiConfig);
        setGateway(InetAddress.getByName(gateway), historyWifiConfig);
        setDNS(InetAddress.getByName(dns), historyWifiConfig);
        
        mWifiManager.updateNetwork(historyWifiConfig); //apply the setting
	}
    
    public void editDhcpWifiConfig(final ScanResult sr,String pwd) throws Exception{        
    	WifiConfiguration historyWifiConfig = getHistoryWifiConfig(sr.SSID);
    	
    	if(historyWifiConfig == null){
    		historyWifiConfig = createComWifiConfig(sr.SSID,pwd);
    		int netId = mWifiManager.addNetwork(historyWifiConfig);
    		mWifiManager.enableNetwork(netId, true);
    	}
    	
        setIpAssignment("DHCP", historyWifiConfig); //"STATIC" or "DHCP" for dynamic setting
        
        mWifiManager.updateNetwork(historyWifiConfig); //apply the setting
	}

    /**
     *  新建wifi配置项
     * @param ssid
     * @param pwd
     * @return
     */
    public WifiConfiguration createComWifiConfig(String ssid,String pwd){
    	WifiConfiguration wc = new WifiConfiguration();
        wc.SSID = "\"" + ssid + "\"";      				//配置wifi的SSID,即该热点的名称,如:TP-link_xxx
        wc.preSharedKey = "\""+ pwd + "\"";            //该热点的密码
        wc.hiddenSSID = true;
        wc.status = WifiConfiguration.Status.ENABLED;
        wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        return wc;
    }
    
    /**
     * 查找已经设置好的Wifi
     * @param ssid
     * @return
     */
    public WifiConfiguration getHistoryWifiConfig(String ssid){
    	List<WifiConfiguration> localList = mWifiManager.getConfiguredNetworks();
        for(WifiConfiguration wc : localList){
        	if(("\"" + ssid + "\"").equals(wc.SSID)){
        		return wc;
        	}
        	mWifiManager.disableNetwork(wc.networkId);
        }
        return null;
    }
  
	public static void setIpAssignment(String assign, WifiConfiguration wifiConf)throws SecurityException, IllegalArgumentException,NoSuchFieldException, IllegalAccessException {
		setEnumField(wifiConf, assign, "ipAssignment");
	}

	public static void setIpAddress(InetAddress addr, int prefixLength,WifiConfiguration wifiConf) throws SecurityException,IllegalArgumentException,
	NoSuchFieldException,IllegalAccessException, NoSuchMethodException,ClassNotFoundException, InstantiationException,InvocationTargetException {
		Object linkProperties = getField(wifiConf, "linkProperties");
		if (linkProperties == null)
			return;
		Class laClass = Class.forName("android.net.LinkAddress");
		Constructor laConstructor = laClass.getConstructor(new Class[] {InetAddress.class, int.class });
		Object linkAddress = laConstructor.newInstance(addr, prefixLength);
		ArrayList mLinkAddresses = (ArrayList) getDeclaredField(linkProperties,"mLinkAddresses");
		mLinkAddresses.clear();
		mLinkAddresses.add(linkAddress);
	}

	public static void setGateway(InetAddress gateway,WifiConfiguration wifiConf) throws SecurityException,IllegalArgumentException,
	NoSuchFieldException,IllegalAccessException, ClassNotFoundException,NoSuchMethodException, InstantiationException,InvocationTargetException {
		Object linkProperties = getField(wifiConf, "linkProperties");
		if (linkProperties == null)
			return;
		Class routeInfoClass = Class.forName("android.net.RouteInfo");
		Constructor routeInfoConstructor = routeInfoClass.getConstructor(new Class[] { InetAddress.class });
		Object routeInfo = routeInfoConstructor.newInstance(gateway);
		ArrayList mRoutes = (ArrayList) getDeclaredField(linkProperties,"mRoutes");
		mRoutes.clear();
		mRoutes.add(routeInfo);
	}

	public static void setDNS(InetAddress dns, WifiConfiguration wifiConf) throws SecurityException, IllegalArgumentException,NoSuchFieldException, IllegalAccessException {
		Object linkProperties = getField(wifiConf, "linkProperties");
		if (linkProperties == null)
			return;
		ArrayList<InetAddress> mDnses = (ArrayList<InetAddress>) getDeclaredField(linkProperties, "mDnses");
		mDnses.clear(); // or add a new dns address , here I just want to replace DNS1
		mDnses.add(dns);
	}
	
	public static String getNetworkPrefixLength(WifiConfiguration wifiConf) {
		String address = "";
		try {
			Object linkProperties = getField(wifiConf, "linkProperties");
			if (linkProperties == null)
				return null;
			
			if (linkProperties != null){
				ArrayList mLinkAddresses = (ArrayList) getDeclaredField(linkProperties,"mLinkAddresses");
				if(mLinkAddresses != null && mLinkAddresses.size() > 0){
					Object linkAddressObj = mLinkAddresses.get(0);
					address = linkAddressObj.getClass().getMethod("getNetworkPrefixLength",  new Class[]{}).invoke(linkAddressObj,null) + "";
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return address;
	}
	
	public static InetAddress getIpAddress(WifiConfiguration wifiConf) {
		InetAddress address = null;
		try {
			Object linkProperties = getField(wifiConf, "linkProperties");
			if (linkProperties == null)
				return null;
			
			if (linkProperties != null){
				ArrayList mLinkAddresses = (ArrayList) getDeclaredField(linkProperties,"mLinkAddresses");
				if(mLinkAddresses != null && mLinkAddresses.size() > 0){
					Object linkAddressObj = mLinkAddresses.get(0);
					address = (InetAddress)linkAddressObj.getClass().getMethod("getAddress",  new Class[]{}).invoke(linkAddressObj,null);
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return address;
	}

	public static InetAddress getGateway(WifiConfiguration wifiConf)  {
		InetAddress address = null;
		try {
			Object linkProperties = getField(wifiConf, "linkProperties");
			
			if (linkProperties != null){
				ArrayList mRoutes = (ArrayList) getDeclaredField(linkProperties,"mRoutes");
				if(mRoutes != null && mRoutes.size() > 0){
					Object linkAddressObj = mRoutes.get(0);
					address = (InetAddress)linkAddressObj.getClass().getMethod("getGateway",  new Class[]{}).invoke(linkAddressObj,null);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return address;
	}

	public static InetAddress getDNS(WifiConfiguration wifiConf) {
		InetAddress address = null;
		try {
			Object linkProperties = getField(wifiConf, "linkProperties");
			
			if (linkProperties != null){
				ArrayList<InetAddress> mDnses = (ArrayList<InetAddress>) getDeclaredField(linkProperties, "mDnses");
				if(mDnses != null && mDnses.size() > 0){
					address = (InetAddress)mDnses.get(0);				
				}
			}		
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return address;
	}

	public static Object getField(Object obj, String name) throws SecurityException, NoSuchFieldException,IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getField(name);
		Object out = f.get(obj);
		return out;
	}

	public static Object getDeclaredField(Object obj, String name) throws SecurityException, NoSuchFieldException,IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getDeclaredField(name);
		f.setAccessible(true);
		Object out = f.get(obj);
		return out;
	}

	public static void setEnumField(Object obj, String value, String name) throws SecurityException, NoSuchFieldException,
			IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getField(name);
		f.set(obj, Enum.valueOf((Class<Enum>) f.getType(), value));
	}


    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mReceiver, mIntentFilter);
        if(mWifiManager != null) mWifiManager.startScan();
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);        
    }

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.back:
//			if(mWifiManager != null) mWifiManager.startScan();
			finish();
			break;

		default:
			break;
		}
	}
	
	public void endScanWifi(final List<ScanResult> list){
		runOnUiThread(new Runnable() {			
			@Override
			public void run() {
				if(mWifiAdapter != null){
					mWifiAdapter.setList(list);
					mWifiAdapter.notifyDataSetChanged();
				}	
			}
		});
			
	}
}

<think>我们正在处理用户关于在Android设备上手动设置WiFi的静态IP地址的问题。根据提供的引用,我们可以总结出以下信息: 1. 在Android 2.X时代,通常使用`Settings`类进行设置,但这种方法在Android 3.X及以上版本无效。 2. 引用[2]提到在Android 9.0中实现静态IP设置的核心步骤: - 判断当前WiFi连接是否已经是静态IP,如果不是则调用一个设置静态IP的方法(例如`setWiFiWithStaticIP`)。 - 设置完成后,保存配置、更新配置、断开WiFi并重新连接。 3. 引用[3]指出,每个WiFi网络的配置存储在`android.net.wifi.WifiConfiguration`类中,通过`android.net.wifi.WifiManager`来管理。 因此,我们可以推断,设置静态IP的关键在于修改当前连接的WiFi网络的`WifiConfiguration`,将其IP分配方式设置为静态,并指定IP地址、子网掩码、网关和DNS等参数,然后保存配置并重新连接。 但是,需要注意的是,从Android 10(API 29)开始,由于隐私和安全限制,许多与网络配置相关的操作可能不再允许普通应用执行。因此,用户可能需要系统级权限或者设备管理员权限,或者只能在系统应用中使用。 下面我们将分步骤说明如何在代码中实现静态IP设置。 ### 步骤1:获取WifiManager 首先,我们需要获取`WifiManager`实例。 ```java WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); ``` ### 步骤2:获取当前连接的WiFi网络的配置 我们需要获取当前连接的WiFi网络的`WifiConfiguration`。这通常通过获取已配置的网络列表并匹配当前连接的网络的SSID来实现。 ```java WifiConfiguration wifiConfig = null; List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks(); String currentSsid = getCurrentSsid(); // 需要实现获取当前连接WiFi的SSID的方法 for (WifiConfiguration config : configs) { if (config.SSID != null && config.SSID.equals("\"" + currentSsid + "\"")) { wifiConfig = config; break; } } ``` 注意:`getConfiguredNetworks()`方法在API 21以上被标记为过时,并且从API 29开始,普通应用无法再使用此方法。因此,对于较新的Android版本,可能需要使用其他方法或具有更高的权限。 ### 步骤3:设置静态IP配置 我们需要创建一个`StaticIpConfiguration`对象(或者使用`IpConfiguration`),并设置IP地址、网关、DNS等。 ```java // 创建StaticIpConfiguration对象 StaticIpConfiguration staticIpConfig = new StaticIpConfiguration(); // 设置IP地址、网关、DNS等 InetAddress ipAddress = InetAddresses.parseNumericAddress("192.168.1.100"); int prefixLength = 24; // 子网掩码位数,例如24对应255.255.255.0 staticIpConfig.ipAddress = new LinkAddress(ipAddress, prefixLength); InetAddress gatewayAddress = InetAddresses.parseNumericAddress("192.168.1.1"); staticIpConfig.gateway = gatewayAddress; // 设置DNS staticIpConfig.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); staticIpConfig.dnsServers.add(InetAddresses.parseNumericAddress("8.8.4.4")); ``` 然后,将`wifiConfig`的IP分配方式设置为静态,并应用上面的静态IP配置。 ```java wifiConfig.setIpAssignment(IpAssignment.STATIC); wifiConfig.setStaticIpConfiguration(staticIpConfig); ``` ### 步骤4:保存配置并重新连接 保存配置并重新连接网络。 ```java // 保存配置 wifiManager.saveConfiguration(); // 这个方法在API 26之后被移除 // 更新配置并重新连接 // 在较新的版本中,可能需要使用updateNetwork(WifiConfiguration)方法 int netId = wifiManager.updateNetwork(wifiConfig); if (netId == -1) { // 更新失败,可能需要添加网络 netId = wifiManager.addNetwork(wifiConfig); } // 使网络生效 wifiManager.enableNetwork(netId, true); // 断开当前连接并重新连接 wifiManager.disconnect(); wifiManager.reconnect(); ``` ### 注意事项 1. 权限:需要以下权限 ```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" /> ``` 在Android 6.0以上,还需要运行时权限(如位置权限),因为获取WiFi信息需要位置权限。 2. 兼容性:上述代码在较新的Android版本(尤其是API 26以上)可能无法完全工作,因为一些方法被移除或限制。在API 26及以上,`saveConfiguration()`被移除,而`updateNetwork`和`addNetwork`仍然可用,但需要应用具有目标API级别26或更低,或者应用是系统应用或具有特殊权限。 3. 替代方案:对于高版本Android,官方推荐使用`Network`和`ConnectivityManager`相关API,但设置静态IP的功能并没有公开的API。因此,用户可能需要在系统设置中手动配置,或者设备需要root权限。 ### 总结 在Android设备上以编程方式设置静态IP地址需要操作`WifiConfiguration`,但受到Android版本的限制。对于普通应用,在较新的Android版本上可能无法实现,除非应用具有系统权限或设备已root。 如果用户只是在设备上手动设置(非编程),那么可以按照以下步骤操作: 1. 进入“设置”->“网络和互联网”->“WiFi”。 2. 点击当前连接的WiFi网络。 3. 点击“编辑”(可能是铅笔图标或高级选项)。 4. 在IP设置中选择“静态”。 5. 输入IP地址、网关、网络前缀长度(即子网掩码,如24)和DNS。 6. 保存。 §§相关问题§§ 1. 在Android 10及以上版本如何以编程方式设置静态IP2. 设置静态IP需要哪些权限? 3. 如何获取当前连接的WiFi网络的SSID? 4. 为什么在Android高版本上设置静态IP更困难?</think>### Android 手动配置 WiFi 静态 IP 地址方法 在 Android 设备上手动设置静态 IP 地址,不同版本的操作方法有所差异。以下是详细步骤和注意事项: #### **Android 9.0 及以上版本** 1. **进入 Wi-Fi 设置** `设置 → 网络和互联网 → Wi-Fi` 2. **选择目标网络** 长按已连接的 Wi-Fi 网络 → 点击"修改网络" 3. **启用静态 IP** - 展开"高级选项" - 将"IP 设置"从 **DHCP** 改为 **静态** 4. **配置参数** ``` IP 地址:192.168.x.xxx (需在路由器网段内) 网关:路由器地址 (通常为 192.168.x.1) 网络前缀长度:24 (对应子网掩码 255.255.255.0) DNS 1:8.8.8.8 (Google DNS) 或运营商 DNS DNS 2:8.8.4.4 (备用 DNS) ``` 5. **保存设置** 点击"保存" → 系统自动断开并重连 Wi-Fi[^2] #### **Android 8.0 及以下版本** 1. `设置 → Wi-Fi` 2. 长按目标网络 → 选择"修改网络配置" 3. 勾选"显示高级选项" 4. 将"IP 设置"改为 **静态** 5. 填写上述 IP 参数 → 保存 --- ### **编程实现静态 IP (需系统权限)** 对于系统应用开发,核心代码如下: ```java // 获取 WifiManager 实例 WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); // 获取当前网络配置 WifiConfiguration wifiConfig = getCurrentWifiConfig(wifiManager); // 设置静态 IP StaticIpConfiguration staticIpConfig = new StaticIpConfiguration.Builder() .setIpAddress(new LinkAddress(InetAddress.getByName("192.168.1.100"), 24)) .setGateway(InetAddress.getByName("192.168.1.1")) .setDnsServers(Arrays.asList(InetAddress.getByName("8.8.8.8"))) .build(); wifiConfig.setIpAssignment(IpAssignment.STATIC); wifiConfig.setStaticIpConfiguration(staticIpConfig); // 应用配置 wifiManager.updateNetwork(wifiConfig); // 返回 networkId wifiManager.saveConfiguration(); wifiManager.disconnect(); wifiManager.reconnect(); // 触发重连使配置生效[^2][^3] ``` --- ### **关键注意事项** 1. **权限要求** - 普通应用无法直接修改 IP 配置(需系统签名或设备管理员权限) - 必须声明权限: ```xml <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> ``` 2. **版本兼容性问题** - Android 3.x+ 已弃用早期 `Settings.System` 方法[^1] - Android 10+ 对非系统应用限制更严格(需用户手动操作) 3. **参数验证** - IP 地址必须在路由器 DHCP 范围外 - 错误的网关/DNS 会导致无法上网 - 网络前缀长度对应子网掩码(如 24=255.255.255.0) --- ### **常见问题解决方案** | 问题现象 | 解决方法 | |---------|---------| | 保存后无法连接 | 检查网关是否与路由器地址一致 | | DNS 解析失败 | 尝试备用 DNS(如 114.114.114.114) | | 配置被自动重置 | 关闭路由器的 DHCP 冲突检测功能 | | 高版本无法编程修改 | 引导用户到系统设置手动操作 | > ⚠️ **重要提示**:普通应用无法绕过系统限制直接修改 IP,需通过 `Intent` 引导用户到系统设置界面: > ```java > startActivity(new Intent(Settings.ACTION_WIFI_IP_SETTINGS)); > ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值