最近做的ANdroid项目是有关于利用ping的方法去获取丢包率。
方案一(失败):
1、ping.c文件在JNI的实现。ping.c文件与其相关文件从Busybox源码(busybox-1.19.2)里拿,或是Android源码的\external\ping\目录下拿。
在jni下编译自己的.so文件。但是实验不成功。
追踪方法:用log在.c打印信息
需要声明
#include
#define LOG_TAG "zyp"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
且要在Android.mk文件添加LOCAL_LDLIBS :=-llog(需要放在include $(CLEAR_VARS)后面的任意位置)
就可以使用:
LOGI("ping= %f",a);打印自己要的信息
追踪发现在创建ICMP协议的socket会失败出错。查找资源原因是必须程序是Root权限才可以。
采用办法是且要在
Java:Process process = Runtime.getRuntime().exec(“su”);
也是失败。原因是因为Runtime.getRuntime().exec(“su”);只是开启一个“Root”的进程,程序还是没有获得Root权限去创建Socket。
方案二(需要Root):
把jni的ping.c与相关文件编译成可执行的二进制文件,Android.mk文件采用Busybox源码(busybox-1.19.2)里拿,或是Android源码的\external\ping\目录下的Android.mk文件,用cygwin编译,编译成可执行文件ping。拷贝发到工程的assets目录下。
复制assets目录下的ping到私有文件目录下/data/data/pakeage_/files/ping
/**
* 复制assets目录下的ping到私有文件目录下ping下。
*/
private boolean cpPingLib(){
String path = TestPing.this.getApplicationContext().getFilesDir()
.getAbsolutePath()+ "/ping"; //data/data/包名/files/
File file = new File(path);
if(file.exists()){
return true;
}
FileOutputStream out = null;
InputStream in = null ;
try {
in = TestPing.this.getAssets().open("ping"); //从assets目录下复制
out = new FileOutputStream(file);
int length = -1;
byte[] buf = new byte[1024];
while ((length = in.read(buf)) != -1){
out.write(buf, 0, length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {