Android 连接wifi 检测是否需要portal 认证

Posted 徐昊Xiho

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 连接wifi 检测是否需要portal 认证相关的知识,希望对你有一定的参考价值。

前言

最近在做一个新需求,就是针对开机欢迎引导页,当连接如星巴克,KFC,地铁上等公共场所的WIFI时,都需要认证功能,而我要调起这个认证页面呈现给用户,登陆任何网页会跳转到wifi得认证页面,输入账号密码,点击验证,能够验证wifi,并保证手机网络能正常使用。某些手机管家软件在手机连接上CMCC等wifi时,会弹出通知栏提示跳转到webview去进行portal验证。而我由于各种限制原因,并不能自动调用,就需要自己来处理这些功能了,而他们是怎样检测的呢?请往下看~

正文

我们的目标很明确,就是要在wifi连接后,判断wifi是否需要portal验证?如果需要portal验证,那么我们直接启动一个Activity,默认用WebView去加载一个网页,比如:http://XXX.com,服务器就会去检测当前网络是否需要验证(Google会进行一个http的访问,如果返回码为204,就证明手机当前连接的wifi,是不需要进行portal验证的)portal 检测到有新的连接,就会去劫持wifi路由,强制访问wifi的portal验证网页,用户只要完成验证,就可以使用该网络了,实现原理如下:

     /**
     * 验证当前wifi是否需要Portal验证
     * @return
     */  
    private boolean isWifiSetPortal() 
        String mWalledGardenUrl = "http://g.cn/generate_204";
        // 设置请求超时
        int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
        HttpURLConnection urlConnection = null;
        try 
            URL url = new URL(mWalledGardenUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setInstanceFollowRedirects(false);
            urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setUseCaches(false);
            urlConnection.getInputStream();
            // 判断返回状态码是否204
            return urlConnection.getResponseCode()!=204;
         catch (IOException e) 
            //   e.printStackTrace();
            return false;
         finally 
            if (urlConnection != null) 
                //释放资源
                urlConnection.disconnect();
            
        
    

这块验证一般放在网络改变的广播接受者里面处理的action.equals(ConnectivityManager.CONNECTIVITY_ACTION

把验证方法封装一下就可以判断使用了,很简单吧~~

package woyou.welcome.api;

import android.os.AsyncTask;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Xiho on 11:09
 * MyBlog: xuhaoblog.com
 * GitHub: github.com/git-xuhao
 * Function:
 */
public class CheckWifiLoginTask extends AsyncTask<Integer,Integer,Boolean> 


    private ICheckWifiCallBack mCallBack;


    public CheckWifiLoginTask (ICheckWifiCallBack mCallBack)
        super();
        this.mCallBack=mCallBack;
    


    @Override
    protected Boolean doInBackground(Integer... params) 
        return isWifiSetPortal();
    

    @Override
    protected void onPostExecute(Boolean result) 
        if (mCallBack != null) 
            mCallBack.portalNetWork(result);
        
    

    /**
     * 验证当前wifi是否需要Portal验证
     * @return
     */
    private boolean isWifiSetPortal() 
        String mWalledGardenUrl = "http://g.cn/generate_204";
        // 设置请求超时
        int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
        HttpURLConnection urlConnection = null;
        try 
            URL url = new URL(mWalledGardenUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setInstanceFollowRedirects(false);
            urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setUseCaches(false);
            urlConnection.getInputStream();
            // 判断返回状态码是否是204
            return urlConnection.getResponseCode()!=204;
         catch (IOException e) 
            //   e.printStackTrace();
            return false;
         finally 
            if (urlConnection != null) 
                //释放资源
                urlConnection.disconnect();
            
        
    

    /**
     * 检测Wifi 是否需要portal 认证
     * @param callBack
     */
    public static void checkWifi(ICheckWifiCallBack callBack)
        new CheckWifiLoginTask(callBack).execute();
    

    public interface ICheckWifiCallBack
        void portalNetWork(boolean isLogin);
    


在广播接收里判断网络是否需要portal认证:


    /** * 接受网络改变的广播  */
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() 
        @Override
        public void onReceive(Context mContext, Intent intent) 
            String action = intent.getAction();
            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) 
                //.....省略逻辑
                portalWifi();
             
        
    ;

/** wifi 认证 检测 **/
    private void portalWifi() 
        CheckWifiLoginTask.checkWifi(new CheckWifiLoginTask.ICheckWifiCallBack() 
            @Override
            public void portalNetWork(boolean isLogin) 
                //不需要wifi认证
                if(!isLogin)
                   //TODO... 
                else 
                   //TODO...
                
            
        );
    

实现原理很简单吧~

以上是关于Android 连接wifi 检测是否需要portal 认证的主要内容,如果未能解决你的问题,请参考以下文章

Android检测到没有数据连接

浏览器判断ios是不是连接wifi

检测 3G 或 Wifi 网络恢复

BroadcastReceiver 不工作(检测是不是连接了wifi)

Unity判断网络是否连接以及判断是否连接WiFi

Android -- WiFi的NUD检测机制浅析