关于 android 5.0-7.1.2 网络图标上的感叹号及其解决办法
叹号杀手源码在此:https://github.com/Noisyfox/NoExclamation
最新版本下载地址:https://github.com/Noisyfox/NoExclamation/releases
7.1.2
谷歌又玩我23333
自7.1.2(开始?),”captive_portal_detection_enabled”设置已被废弃,现在改为了”captive_portal_mode”选项,该选项可设置为以下3种值:
- 0:彻底禁用检测(Don’t attempt to detect captive portals.)
- 1:检测到需要登录则弹窗提醒(默认值)(When detecting a captive portal, display a notification that prompts the user to sign in.)
- 2:检测到需要登录则自动断开此热点并不再自动连接(When detecting a captive portal, immediately disconnect from the network and do not reconnect to that network in the future.)
叹号杀手已经更新以支持该版本。
但愿以后谷歌不要再乱改了233333
感谢 jingyu9575 的帮助 https://github.com/Noisyfox/NoExclamation/issues/2
7.1.1
从7.1.1开始,检测用的服务器地址储存格式发生了变化,改为了:
private static String getCaptivePortalServerHttpsUrl(Context context) { return getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL); }
以及
public static String getCaptivePortalServerHttpUrl(Context context) { return getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTP_URL, DEFAULT_HTTP_URL); }
可以看到,系统不会自动加入”generate_204″的后缀了,这意味着url可以设计的更加灵活,同时也意味着在设置的时候需要填入完整的url:
adb shell "settings put global captive_portal_https_url https://www.noisyfox.cn/generate_204"
当然如果只有http的话,可以执行:
adb shell "settings put global captive_portal_use_https 0" adb shell "settings put global captive_portal_http_url http://www.noisyfox.cn/generate_204"
复原方法见下文。
7.0-7.1.0
需要服务器支持https。
或者使用命令
adb shell "settings put global captive_portal_use_https 0"
禁用https即可。
恢复可用
adb shell "settings put global captive_portal_use_https 1"
或者
adb shell "settings delete global captive_portal_use_https"
5.0-6.0
升级了安卓5.0的同学们一定对网络图标上面的那个感叹号感到十分郁闷。安卓5.0引入了一种新的网络评估机制来评估网络状况,当你有网络请求时会自动选择网络连接条件最好的一个网络进行连接。该机制的代码实现如下:
简要来说就是,如果该网络是VPN,那么直接使用这个网络进行连接,否则调用 isCaptivePortal() 函数进行网络状况的判定,再根据判定结果决定是否选用此网络。 而罪魁祸首就是这个 isCaptivePortal() 函数,它会访问 clients3.google.com/generate_204 并根据返回结果来判断网络联通状况。正是这个google的网址被墙导致安卓没有办法评估网络,这样就导致了那个蛋碎的感叹号一直存在,以及wifi用着用着突然自动连回数据连接了。
本来我想直接把 isCaptivePortal() 函数给屏蔽掉,让他一直返回成功,但是看了下google的代码,发现这个函数是非常有用处的,为什么呢?这个函数有个非常重要的作用,那就是判断当前网络是否需要登录。
想必大家都连接过那些需要验证才能使用的wifi热点吧,当你们连接这些热点的时候,android会自动弹出提示询问你是否需要登录。而这个功能就是依靠了 isCaptivePortal() 这个函数才得以实现,具体原理如下:
安卓先访问 clients3.google.com/generate_204 这个网址,而这个网址如字面所说,会产生一个 http 204 返回值。204返回值的意思就是空内容。如果当前wifi是需要登录才可以连接,那么当试图访问google的服务器的时候,wifi的验证机制一定会自动跳转到一个登录页面,这个时候http请求的返回值就必然不是204了。就是通过这一机制,便可以区分当前wifi是否需要验证,不得不佩服想出这个办法的人来。
然而这就导致了如果简单的屏蔽掉这个函数的功能,那么就没有办法自动提示登录了,但是如果不屏蔽掉那么这个网址被墙掉了,因此会有一个难看的感叹号。想来想去我想到了一个曲线救国的办法,那就是我们把这个网址改成国内的网址不就可以了?我们自己搭一个服务器,来产生这个204返回值给它,问题不就迎刃而解了吗?
那么下面就给出解决方法(无需root):
1.完全屏蔽网络检查功能,最简单快速,但是就没有办法提示wifi登录:
adb shell "settings put global captive_portal_detection_enabled 0"
2.用国内的服务器替换掉google的服务器:
adb shell "settings put global captive_portal_server noisyfox.cn"
这个服务器是我自己建的,也就是本站:http://noisyfox.cn/ 我在服务器上写了个简单的204页面,网址是 http://noisyfox.cn/generate_204 只要用这个网址替换掉google的网址,就可以正常访问并检测网络状态了。不过由于本人的服务器速度并不快,所以感叹号还是会显示一小会儿的,不过应该很快就会消失。
3.恢复默认值
对于第一条指令,恢复默认只需要执行:
adb shell "settings put global captive_portal_detection_enabled 1"
或者
adb shell "settings delete global captive_portal_detection_enabled"
第二条指令的恢复直接delete即可:
adb shell "settings delete global captive_portal_server"
如果你对本站提供的服务速度不满意,可以在文末找到网友提供的其它服务地址。
是不是看着很舒服呢?烦人的感叹号没有了~
经过靠谱的确认,该修改方式具有持久性,重启依旧有效,除非刷机或者清除数据。
如何建立自己的服务器
1. 对于apache服务器,如果你的服务器安装了rewrite模块,那么只需要在网站的.htaccess中加入以下代码:
<IfModule mod_rewrite.c>; RewriteEngine On RewriteCond %{REQUEST_URI} /generate_204$ RewriteRule $ / [R=204] </IfModule>;
2. 对于nginx,直接加入以下设置即可:
location /generate_204 { return 204; }
3. 如果以上方法都无效,那么就要利用代码中的一个小trick来完成,直接在网站的根目录下建立一个叫做“generate_204”的空文件即可,因为安卓的源码中写了如果返回的内容为空那么也会当成204(毕竟一个空的页面怎么想都不可能是登录页面嘛!)。
一键设置工具(需要root)
锵锵锵!由于有些人不太熟悉adb之类的操作,因此就做了一个小工具方便大家直接在手机上设置!
- 下载地址
最新版请移步:https://github.com/Noisyfox/NoExclamation/releases
叹号杀手 2.0
- 支持 Android 7.1.1
1.5
- 修正了应用崩溃的问题
1.4
- 增加图标
- 替换网址为英文网址
- 优化了重置网址功能
- 优化界面,在修改网址时不会导致界面卡顿
一些其它服务网址
我会尽我所能提供长期有效的服务,但是由于本站服务器不是很快,而且网络状况有时候会不稳定,因此无法保证100%可靠的服务。不过有一些热心网友提供了其它服务网址,速度和稳定性或许会比本站要好。故在此特别列出供大家选用。如果给提供者带来不便之处请回复告知,我会及时删除。
by fengz: captive.v2ex.co V2EX建立的服务,速度不错,稳定性也很不错,具体信息请查看 https://www.v2ex.com/t/303889
by lkebin: liukebin.avosapps.com 架设于LeanCloud服务器,据lkebin称是永久有效
by Zohar: www.iwch.me 热心网友的个人站点
请问能不能放出代码便于其他人也方便搭建204页面~
也谢谢作者找出来感叹号的原因~
直接新建一个php文件,输入:
即可,注意一点就是这个页面的url结尾必须是generate_204,因为这是直接用代码写死在系统里面的,只有前面的域名可以修改
谢谢大牛,欢快的去测试一下~
只要能返回 204的status code就行
我在apache搭建的站点根目录下建立了generate_204文件夹,里面是index.php 内容为博主提供的php代码,电脑访问为空白页面,但填到手机里就不行,望博主指点
解决了,是我思路错了,不应该是建目录的方式而是要建立generate_204.php然后在URL里去掉扩展名,我的方法是使用.htaccess的重写功能:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]+)$ $1.php [NC,L]
恩恩我也是用的rewrite
请问generate_204.php这个文件放在网站的二级目录行不行?
目前有http://xycabin.com/g/generate_204.php这个地址可以访问,我也通过adb shell设置了,目前执行su -c “settings get global captive_portal_server”的结果是:xycabin.com/g/,可等了很久还是有感叹号?
经测试应该是二级目录不行,我换上博主的网址,2秒钟感叹号就没了,可是将这个php文件放在根目录的话我不知道该怎么设置.htaccess了,(二级目录的.htacess是用@worry提供的方法)会不会影响我WP的运行?
改成 xycabin.com/g 就是后面不能有那个斜杠试试看
因为你的地址是xxxxx/generate_204.php,你需要用规则把.php后缀去掉
我的第一个回复没说清楚,我的http://www.xycabin.com/g/generate_204是可以访问的,加不加.php都能访问,且Status code都是204,可还是不行。设置成你的地址或g.cn就可以啦。
您好!本人用联通3G网络 HTC816W刷CM12 nighty最新版 按照教程安装APK并设置重启之后有效,而一旦切换飞行模式再切换回来则sim卡网络无信号,除非重启方能解决,此外,重启机子有概率发生同样无信号的情况(概率为每5次重启有2次出现上述情况)望给予支持 感谢
试了试,nginx可以直接返回204,比用php快多了:
location /generate_204 { return 204; }
+1
嗯好方法~我也改一下我的服务器好了~
果然改成rewrite规则就快好多了
具体是在哪里修改呢?站长?谢谢
直接手机连上电脑用adb执行文中的命令就可以了
修改之后重启后会不会恢复成原来的样子?会不会影响ota升级?
应该是重启就失效,因为现在修改的办法是临时的,不过要永久修改应该也不难。
因为修改这个需要有root权限,所以说如果root了可能会影响ota,本身这个修改是不影响ota的。
额经过最新测试表示,这个是永久有效的(除非刷机或者恢复数据)
上面的php怎么隐藏后缀名?
用一个generate_204目录下放index.php不就行了?
设置一条重写规则就行了,我放在了SAE上,重写规则是:
- rewrite: if( path == "/generate_204" ) goto "/generate_204.php"
http://liukebin.sinaapp.com/generate_204
膜拜技术帝~~
大神能否把服务器架设在SAE上,这样会快很多!
http://liukebin.sinaapp.com/generate_204
终身有效
sae是快
大神我想问下,在SEA上,是怎么做到像你这样liukebin.sinaapp.com打开网址能显示文字,但实际上又能返回204让手机识别的呢?谢谢!
那是因为android实际访问的网址是liukebin.sinaapp.com/generate_204,后面的部分是在代码里面写的所以表面上就看不出来
請問能告訴我代碼嗎,評論我都看了,自己試過但沒成功,能告訴我代碼是什麼嗎?謝謝了!
什么代码?
就是那个打开的连接是liukebin.sinaapp.com但实际访问的是liukebin.sinaapp.com/generate_204的代码,是- rewrite: if( path == “/generate_204” ) goto “/generate_204.php”这句代码吗?在哪个地方添加这句代码呢?是在generate_204空文件下直接添加吗?本人小白一个,想学习一下,麻烦你了。
首先你要明白的是根本不存在所谓的“打开的连接是liukebin.sinaapp.com但实际访问的是liukebin.sinaapp.com/generate_204”,而是安卓本身就是访问的是“liukebin.sinaapp.com/generate_204”这个网址。
以及如何创建这个204页面我的文章最后有明确的方法。
噢,我弄明白了,原来是自己一直在绕圈,现在解决问题了,谢谢您!
大赞!求博主永远别关服务器。
app的下载连接不好使了
现在呢?
可以了~
想知道会不会影响下次的OTA
不会,这个没有修改系统文件的
顶~楼主 从分析到解决,清晰到位!
在手机里下载后,Nexus5表示无法运行啊
今天网上有教:创建个新用户,第一次登陆会试图连接服务器,此时强制关机。再开,感叹号就没了!这是什么原理啊?
改完后G+上不了,恢复默认后也不行
多谢,虽然还没升到5.0……Sony说年初会给升
很赞的想法,不过你考虑过自己的安全吗?建议弄一个别人的服务,亚马逊微软之类的。
话说这个对4.4有效么 那个黄色的图标也蛋疼。。
4.4有这个问题吗?
4.4是橙色的图标,貌似也是这个原因,不显眼罢了。
狐狸,我认为你的办法已经不能在最新系统上解决感叹号的问题了。
首先最新的 5.0.2_r1 tag中已经没有了 android / platform/frameworks/base / 625239a05401bbf18b04d9874cea3f82da7c29a1 / . / core / java / android / net / CaptivePortalTracker.java 文件了,这个文件应该就是狐狸贴出的代码部分,其次,在5.0.2上使用了狐狸的apk,apk检测到“当前的 Portal Server”是 null,所以我猜想作者的办法已经不适用于新版。
多谢提醒。我还没有跟进最新的5.0.2。这几天我会去研究一下最新的代码。
5.0.1下面获取到的Portal Server也是null,但是用作者的命令改了之后仍然可以去掉感叹号,而且获取到的Portal Server也会变成自己改的 那个。不过从adb logcat里面来看,系统除了会检查自己设定的Portal Server,还是会检查client3.google.com,不知道为什么。
新的CM12nightly build9 for One Plug已经是5.0.2了,这个方法仍然好用。
只是博主可能需要在命令里注明一下。
我的手机未root, 尝试用文中的命令,没有报错,但是试了很多次包括多个文中的多个地址都不行。
最好, adb shell “settings put global captive_portal_server g.cn” 解决了我的问题,我就是因为我的手机未root
其实,既然不需要root,也就没有必要在命令中用到su啦
嘛~确实不用root,但是这个只有在adb下才可以不root的说~如果是用终端软件的话还是会有权限问题~
恭喜,贵站被墙了
偶尔会抽风啦,还到不至于被墙~而且https一直是好的
我也是CM12 5.02,还是未成功,具体操作求指导啊
null的时候直接用DEFAULT_SERVER,初始化看一眼就很清楚了.
支持小狐狸!我们会经常来串门。
话说何必动用php呢, nginx或者apache那边就直接拦截下某个地址, 返回个204就好了
欸都可以嘛~
感谢思路!
其实设置成g.cn就可以了,g.cn/generate_204是可以的。电信/移动线路亲测有效……
!!!居然这么炫!
长沙移动4G亲测,g.cn 以及 265.com 都被墙…… 后来用作者的地址OK了
郑州移动同测试被墙,用回作者的地址OK
不行呀大哥。。root过了也授权了 完全没用哇 咋回事儿