实战-Android 认证Wifi 连接后自动弹出认证界面

这篇博客介绍了WiFi的portal认证过程,包括通过Google的默认检查URL来判断是否需要认证,以及在Android系统中如何处理网络监测消息并自动弹出认证框。此外,还展示了如何修改代码以使用自定义服务器地址进行WiFi认证状态的检测。

认证Wifi简介

Wifi Portal
portal认证就是连接Wifi成功后,还需要去一个登录页面,登录后才能正常使用wifi。在现在商店比如肯德基,万科,万达等很多外场,都有这样的认证方式。
Google 官方介绍:
在这里插入图片描述
判断是否是认证WIfi

frameworks/base/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL =
            "http://connectivitycheck.gstatic.com/generate_204";
private void testForCaptivePortal() {
        new Thread(new Runnable() {
            public void run() {
                // Give time for captive portal to open.
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                HttpURLConnection urlConnection = null;
                int httpResponseCode = 500;
                try {
                    urlConnection = (HttpURLConnection) mURL.openConnection();
                    urlConnection.setInstanceFollowRedirects(false);
                    urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
                    urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
                    urlConnection.setUseCaches(false);
                    urlConnection.getInputStream();
                    httpResponseCode = urlConnection.getResponseCode();
                } catch (IOException e) {
                } finally {
                    if (urlConnection != null) urlConnection.disconnect();
                }
                if (httpResponseCode == 204) {
                    done(CAPTIVE_PORTAL_APP_RETURN_APPEASED);
                }
            }
        }).start();
    }

认证WIif自动弹框认证

直接在ConnectivityService 的maybeHandleNetworkMonitorMessage 函数中处理,并跳转:

private boolean maybeHandleNetworkMonitorMessage(Message msg) {
	 case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
	 	...
	 	 PendingIntent intent = (PendingIntent) msg.obj;
         if (DBG) log("start PendingIntent");
         intent.send();
}

完整修改记录:

--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2288,6 +2288,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
                     final boolean visible = toBool(msg.arg1);
                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
                     // If captive portal status has changed, update capabilities or disconnect.
+                    if (DBG) log("Avoiding captive portal network: " + nai);
                     if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
                         final int oldScore = nai.getCurrentScore();
                         nai.lastCaptivePortalDetected = visible;
@@ -2310,8 +2311,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
                             break;
                         }
                         if (!nai.networkMisc.provisioningNotificationDisabled) {
+                            if (DBG) log("Avoiding captive portal network: showNotification");
                             mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null,
                                     (PendingIntent) msg.obj, nai.networkMisc.explicitlySelected);
+                            if (nai.networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
+                                try {
+                                    PendingIntent intent = (PendingIntent) msg.obj;
+                                    if (DBG) log("start PendingIntent");
+                                    intent.send();
+                                } catch (PendingIntent.CanceledException e) {
+                                    log("PendingIntent.CanceledException " + e.toString());
+                                    e.getStackTrace();
+                                }
+                            }
                         }
                     }
                     break;
-- 

使用自定义的服务器地址判断是否Wifi Port成功:

--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -71,12 +71,16 @@ import java.lang.reflect.Method;
 import java.util.Objects;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicBoolean;
+import android.os.SystemClock;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;

 public class CaptivePortalLoginActivity extends Activity {
     private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
-
+    private static final String DEFAULT_SERVER = "xxx.xxx.xxx";//自定义的服务器
     private static final int SOCKET_TIMEOUT_MS = 10000;

     private enum Result {
@@ -302,11 +306,11 @@ public class CaptivePortalLoginActivity extends Activity {
     }

     private URL getUrl() {
-        String url = getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
-        if (url == null) {
-            url = mCm.getCaptivePortalServerUrl();
+        try {
+            return new URL("http",DEFAULT_SERVER, "/link.html?t=" + SystemClock.uptimeMillis());
+        }catch (MalformedURLException|NumberFormatException e) {
+            return null;
         }
-        return makeURL(url);
     }

     private static URL makeURL(String url) {
@@ -342,6 +346,7 @@ public class CaptivePortalLoginActivity extends Activity {
                 }
                 HttpURLConnection urlConnection = null;
                 int httpResponseCode = 500;
+                String msg = "";
                 String locationHeader = null;
                 try {
                     urlConnection = (HttpURLConnection) network.openConnection(mUrl);
@@ -354,13 +359,22 @@ public class CaptivePortalLoginActivity extends Activity {
                     }
                     // cannot read request header after connection
                     String requestHeader = urlConnection.getRequestProperties().toString();
-
+                    InputStream input = urlConnection.getInputStream();
+                    BufferedReader br = new BufferedReader(new InputStreamReader(input));
+                    String line = null;
+                    StringBuffer sb = new StringBuffer();
+                    }
+                    input.close();
+                    msg = sb.toString();
                     urlConnection.getInputStream();
                     httpResponseCode = urlConnection.getResponseCode();
                     locationHeader = urlConnection.getHeaderField(HTTP_LOCATION_HEADER_NAME);
                     if (DBG) {
                         Log.d(TAG, "probe at " + mUrl +
                                 " ret=" + httpResponseCode +
+                                " msg=" + msg +
                                 " request=" + requestHeader +
                                 " headers=" + urlConnection.getHeaderFields());
                     }
@@ -368,7 +382,7 @@ public class CaptivePortalLoginActivity extends Activity {
                 } finally {
                     if (urlConnection != null) urlConnection.disconnect();
                 }
-                if (isDismissed(httpResponseCode, locationHeader, mProbeSpec)) {
+                if (!TextUtils.isEmpty(msg) && msg.contains("success")) {//返回SUCCESS 表示认证WIIF成功
                     done(Result.DISMISSED);
                 }
             }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值