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. ...
随机推荐
- c#读写apk的 comment
写入: ZipFile zipFile = new ZipFile("C:\\Users\\Administrator\\Desktop\\2.apk"); zipFile.Beg ...
- mac中git使用
配置用户名及邮箱在使用Git提交前,必须配置用户名和邮箱,这些信息会永久保存到历史记录中.git config --global user.name "xxxxxx"git con ...
- 【转】IP报文格式详解
下图为常见的IP报文格式表: 上面是IP的报文格式,接下来我们先说明各个字段的意义.然后,用Etheral软件转包分析IP的报文格式. 1.版本:ip报文中,版本占了4位,用来表示该协议采用的是那一个 ...
- Java Decompiler反编译Jar文件
1.重新编译已经打包的Jar包,使用 Java Decompiler 打开需要重新编译的jar包,找到自己需要自己修改的Class文件 ,修改之后电子保存文件 ,保存的时候编译工具自动将class文件 ...
- GCC使用总结
概念 GCC一开始是linux系统集成的用来编译C程序的编译器(GNU C Compiler),目前GCC已经不仅仅支持C语言了,因而其缩写名单意义也变成(GNU Compiler Collectio ...
- java中List与数组的转换
1.数组转换成List public static <T> List<T> asList(T... a) String[] arr = new String[] {" ...
- Burp Suite的代理Brup Proxy的使用详解
Burp Proxy 是Burp Suite以用户驱动测试流程功能的核心,通过代理模式,可以让我们拦截.查看.修改所有在客户端和服务端之间传输的数据.
- Mycat简单配置
最近项目中需要用到Mycat来作为Mysql的分表中间件.所以稍微研究了一下. Mycat使用起来是非常方便,而且最重要的是配置简单,稍显麻烦的就是需要对库中的每一个表都进行配置. 记录一下最重要的几 ...
- javamail: UrlDataSource获取网络文件作为邮件的附件|javamail发送二进制流附件的问题
https://www.cnblogs.com/younldeace/p/5193103.html 最近做个邮件发送功能,要内嵌图片并有附件. 需求很奇怪,图片和附件文件是放在ftp服务器上的,查了下 ...
- QQ首页 案例
一.知识点 ①background-attachment属性设置背景图像是否固定或者随着页面的其余部分滚动.scroll默认值.背景图像会随着页面其余部分的滚动而移动.fixed当页面的其余部分滚动时 ...