Android10 system application wifi connection and static ip proxy settings

Android10 system application wifi connection and static ip proxy settings

If you are developing wifi on Android 10 or a newer Android version, this article may be of some help to you.

Android wifi connection and static ip proxy settings are mainly for system applications

Main code for wifi connection:

Android 9 and previous versions connect to the network code:

   // 添加一个网络并连接     
    public void addNetwork(WifiConfiguration wcg) {    
     int wcgID = mWifiManager.addNetwork(wcg);    
     boolean b =  mWifiManager.enableNetwork(wcgID, true);    
    }    
     

After Android 10, the system application cannot use the above method to connect to the network, and the following method is required:


    protected void connect(WifiConfiguration config) {
        WifiManager wifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);
        wifiManager.connect(config, connectListener); //所有的数据都在config对象里面;connectListener 没啥作用,一般传null参数,不管密码是否正确都是回调success。
    }


Whether it is a wifi connection found through scanning or an added network connection, the above wifiManager.connect method must be called.

The connect method is described in WifiManager:

    @hide
    @SystemApi
    @RequiresPermission(anyOf = {
            android.Manifest.permission.NETWORK_SETTINGS,
            android.Manifest.permission.NETWORK_SETUP_WIZARD,
            android.Manifest.permission.NETWORK_STACK
    })
    public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
        ...
    }

It means that ordinary applications cannot be adjusted, and it is a system api, which requires some system permissions.

WifiConfiguration object construction

The WifiConfiguration object contains the information entered by our application, such as: wifi name, wifi password, encryption form, whether there is a static ip, whether there is a proxy setting.

The wifi name, wifi password, and encryption form are all set in the same form,
and the data related to static ip and proxy information is encapsulated by the IpConfiguration object.

The object information that needs to be set is as follows:

WifiConfiguration config = new WifiConfiguration();

//wifi名称
config.SSID = "XXXName";//wifi名称,一般通过扫描获取
config.networkId = "XXXId";//wifiId,非扫描的情况,比如添加wifi的情况,可以不写


//wifi加密形式,不加密的wifi,无需设置密码

//wifi密码
config.preSharedKey = "\""+Password+"\""; 
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.XXX); //加密形式,XXX为NONE/WPA_PSK/WPA_EAP
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.XXX); //验证算法,XXX为OPEN/SHARED,NONE的情况无需设置


//静态ip相关数据和代理相关数据

IpAssignment mIpAssignment = IpAssignment.DHCP;//静态配置,静态默认是:DHCP,如果是静态ip:IpAssignment.STATIC;
StaticIpConfiguration mStaticIpConfiguration = null;//静态ip,才有必要设置,否则传入null即可
ProxySettings mProxySettings = ProxySettings.UNASSIGNED; //代理情况,是否静态ip
ProxyInfo mHttpProxy = null; //代理的参数数据保存对象,无代理的情况可不用实例化,传入null即可



    //设置静态ip相关数据
    mStaticIpConfiguration = new StaticIpConfiguration();
    Inet4Address inetAddr = (Inet4Address) NetworkUtils.numericToInetAddress("ipString");//ipString为静态ip地址,NetworkUtils是系统net的工具类
    mStaticIpConfiguration.ipAddress = new LinkAddress(inetAddr, networkPrefixLength); //IP前缀长度,networkPrefixLength是0-32的数值,一般设置24
    InetAddress gatewayAddr = (Inet4Address) NetworkUtils.numericToInetAddress("gatewayIp");//gatewayIp为网关地址
    mStaticIpConfiguration.gateway = gatewayAddr;
    Inet4Address dnsAddr = (Inet4Address) NetworkUtils.numericToInetAddress("dnsString");//dns为域名地址
    mStaticIpConfiguration.dnsServers.add(dnsAddr);//域名可以添加多个,一般手机是显示可添加两个
    
    //代理设置,分为NONE无/MANUAL手动/PAC自动
    mProxySettings = ProxySettings.STATIC;//无:ProxySettings.NONE; 自动:ProxySettings.PAC
    //手动代理最为常见,需要填入三个数据:host为主机名称,port为服务器端口,exclusionList为绕过的地址(多个的情况可使用,号分隔)
    mHttpProxy = new ProxyInfo(host, port, exclusionList); 
    
    //自动代理用得不多,只需输入一个PAC网址即可:
    //Uri uri = Uri.parse("pac_ip");
    //mHttpProxy = new ProxyInfo(uri); 
    
//最后把静态ip和代理相关数据设置到IpConfiguration对象中即可
IpConfiguration ipConfiguration = new IpConfiguration(mIpAssignment,mProxySettings,mStaticIpConfiguration,mHttpProxy);
config.setIpConfiguration(ipConfiguration);

If there is no static ip or proxy settings, setIpConfiguration may not be called.

There are a lot of specific judgment logics that are omitted here. After all, the logic of system code judgments is too specific and there will be many.

The specific agent will not be posted. There are too many judgments on relevant conditions, such as various non-empty situations, which will look more chaotic.

other

If it is an ordinary application, you should not be able to set static ip and proxy, only simple connection;

And Android10 or later versions, ordinary applications can only use ConnectivityManager to connect

Similarly, after Android 10, the wifi switch and other setting methods are also invalid, but the methods of obtaining the status of the wifi switch, scanning wifi, and obtaining the wifi list are still normal.

If you want to see why the previous connection method failed, you can take a look at WifiServiceImp.java, which contains the logic code that returns false directly.

The following is an example of entering the wifi name and password to connect to an Android 10 common app:


@RequiresApi(api = Build.VERSION_CODES.Q)
    private boolean connectAP_Q(String ssid, String pass) throws InterruptedException {

        ConnectivityManager connectivityManager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
                .setSsidPattern(new PatternMatcher(ssid, PatternMatcher.PATTERN_PREFIX))
                .setWpa2Passphrase(pass)
                .build();
        //创建一个请求
        NetworkRequest request = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)//创建的是WIFI网络。
                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)//网络不受限
                .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)//信任网络,增加这个连个参数让设备连接wifi之后还联网。
                .setNetworkSpecifier(specifier)
                .build();
        connectivityManager.requestNetwork(request, new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
               //TODO 连接OK,做些啥
            }

            @Override
            public void onUnavailable() {
               //TODO 连接失败,或者被用户取消了,做些啥
            }
        });
    }
    

It is found that after the call is still required to seek the consent of the system application, the network connection can be made!

After Android 10, the permissions were tightened, resulting in smaller permissions for ordinary applications, and wifi is only one part of it.

Mutual encouragement: Work hard to learn the knowledge you should master.

Guess you like

Origin blog.csdn.net/wenzhi20102321/article/details/123675077
Recommended