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

被折叠的 条评论
为什么被折叠?



