A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈君 金牌黑马   /  2014-9-20 21:22  /  1216 人查看  /  0 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

Android应用很多时候都会涉及到网络,在请求网络出错时,我们可以通过抓包来分析网络请求,返回的数据等,通常我们是用tcpdump这个工具来抓包,再通过wireshark工具来分析生成的文件,关于tcpdump的使,可以从网上查一下,有很多介绍,比如:http://www.cnblogs.com/likwo/archive/2012/09/06/2673944.html。关于如何用wireshark来分析文件,本文不作介绍。

使用adb的命令来操作,还是比较麻烦,所以我写了一个应用,把这些命令封装了起来。实现的最根本的原理是通过Runtime.exec来执行linux命令。
实现代码
CommandsHelper.java
  1. /**
  2. *
  3. * @author lihong06
  4. * @since 2014-3-3
  5. */
  6. public class CommandsHelper {
  7. private static final String NAME = "<a title="tcpdump" href="http://www.android-study.com/wangluobiancheng/570.html">tcpdump</a>";
  8. private static final String TAG = "CommandsHelper";
  9. public static final String DEST_FILE = Environment.getExternalStorageDirectory() + "/capture.pcap";

  10. public static boolean startCapture(Context context) {
  11. InputStream is = null;
  12. OutputStream os = null;
  13. boolean retVal = false;
  14. try {
  15. AssetManager am = context.getAssets();
  16. is = am.open(NAME);
  17. File sdcardFile = Environment.getExternalStorageDirectory();
  18. File dstFile = new File(sdcardFile, NAME);
  19. os = new FileOutputStream(dstFile);

  20. copyStream(is, os);

  21. String[] commands = new String[7];
  22. commands[0] = "adb shell";
  23. commands[1] = "su";
  24. commands[2] = "cp -rf " + dstFile.toString() + " /data/local/<a title="tcpdump" href="http://www.android-study.com/wangluobiancheng/570.html">tcpdump</a>";
  25. commands[3] = "rm -r " + dstFile.toString();
  26. commands[4] = "chmod 777 /data/local/<a title="tcpdump" href="http://www.android-study.com/wangluobiancheng/570.html">tcpdump</a>";
  27. commands[5] = "cd /data/local";
  28. commands[6] = "<a title="tcpdump" href="http://www.android-study.com/wangluobiancheng/570.html">tcpdump</a> -p -vv -s 0 -w " + DEST_FILE;

  29. execCmd(commands);
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. Log.i(TAG, " error: " + e.getMessage());
  33. } finally {
  34. closeSafely(is);
  35. closeSafely(os);
  36. }

  37. return retVal;
  38. }

  39. public static void stopCapture(Context context) {
  40. // 找出所有的带有<a title="tcpdump" href="http://www.android-study.com/wangluobiancheng/570.html">tcpdump</a>的进程
  41. String[] commands = new String[2];
  42. commands[0] = "adb shell";
  43. commands[1] = "ps|grep <a title="tcpdump" href="http://www.android-study.com/wangluobiancheng/570.html">tcpdump</a>|grep root|awk '{print $2}'";
  44. Process process = execCmd(commands);
  45. String result = parseInputStream(process.getInputStream());
  46. if (!TextUtils.isEmpty(result)) {
  47. String[] pids = result.split("\n");
  48. if (null != pids) {
  49. String[] killCmds = new String[pids.length];
  50. for (int i = 0; i < pids.length; ++i) {
  51. killCmds[i] = "kill -9 " + pids[i];
  52. }
  53. execCmd(killCmds);
  54. }
  55. }
  56. }

  57. public static Process execCmd(String command) {
  58. return execCmd(new String[] { command }, true);
  59. }

  60. public static Process execCmd(String[] commands) {
  61. return execCmd(commands, true);
  62. }

  63. public static Process execCmd(String[] commands, boolean waitFor) {
  64. Process suProcess = null;
  65. try {
  66. suProcess = Runtime.getRuntime().exec("su");
  67. DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
  68. for (String cmd : commands) {
  69. if (!TextUtils.isEmpty(cmd)) {
  70. os.writeBytes(cmd + "\n");
  71. }
  72. }
  73. os.flush();
  74. os.writeBytes("exit\n");
  75. os.flush();
  76. } catch (IOException e) {
  77. e.printStackTrace();
  78. }

  79. if (waitFor) {
  80. boolean retval = false;
  81. try {
  82. int suProcessRetval = suProcess.waitFor();
  83. if (255 != suProcessRetval) {
  84. retval = true;
  85. } else {
  86. retval = false;
  87. }
  88. } catch (Exception ex) {
  89. Log.w("Error ejecutando el comando Root", ex);
  90. }
  91. }

  92. return suProcess;
  93. }

  94. private static void copyStream(InputStream is, OutputStream os) {
  95. final int BUFFER_SIZE = 1024;
  96. try {
  97. byte[] bytes = new byte[BUFFER_SIZE];
  98. for (;;) {
  99. int count = is.read(bytes, 0, BUFFER_SIZE);
  100. if (count == -1) {
  101. break;
  102. }

  103. os.write(bytes, 0, count);
  104. }
  105. } catch (IOException e) {
  106. e.printStackTrace();
  107. }
  108. }

  109. private static void closeSafely(Closeable is) {
  110. try {
  111. if (null != is) {
  112. is.close();
  113. }
  114. } catch (IOException e) {
  115. e.printStackTrace();
  116. }
  117. }

  118. private static String parseInputStream(InputStream is) {
  119. InputStreamReader isr = new InputStreamReader(is);
  120. BufferedReader br = new BufferedReader(isr);
  121. String line = null;
  122. StringBuilder sb = new StringBuilder();
  123. try {
  124. while ( (line = br.readLine()) != null) {
  125. sb.append(line).append("\n");
  126. }
  127. } catch (IOException e) {
  128. e.printStackTrace();
  129. }

  130. return sb.toString();
  131. }
  132. }
复制代码

MainActivity.java
  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);

  6. final TextView textView = (TextView) findViewById(R.id.textView1);
  7. String oldText = textView.getText().toString();
  8. textView.setText(oldText + "\n\n" + "目标文件: " + CommandsHelper.DEST_FILE);

  9. findViewById(R.id.start_capture).setOnClickListener(new View.OnClickListener() {
  10. @Override
  11. public void onClick(View v) {
  12. v.setEnabled(false);
  13. new Thread(new Runnable() {
  14. @Override
  15. public void run() {
  16. final boolean retVal = CommandsHelper.startCapture(MainActivity.this);
  17. runOnUiThread(new Runnable() {
  18. @Override
  19. public void run() {
  20. Toast.makeText(MainActivity.this, "startCapture result = " + retVal, Toast.LENGTH_SHORT).show();
  21. }
  22. });
  23. }
  24. }).start();
  25. }
  26. });

  27. findViewById(R.id.stop_capture).setOnClickListener(new View.OnClickListener() {
  28. @Override
  29. public void onClick(View v) {
  30. CommandsHelper.stopCapture(MainActivity.this);
  31. findViewById(R.id.start_capture).setEnabled(true);
  32. }
  33. });
  34. }

  35. @Override
  36. public boolean onCreateOptionsMenu(Menu menu) {
  37. // Inflate the menu; this adds items to the action bar if it is present.
  38. getMenuInflater().inflate(R.menu.main, menu);
  39. return true;
  40. }
  41. }
复制代码

说明
1、手机必须要Root,没有root的我没有测试过,另外,我也只测试了我一台手机,没有覆盖到所有的手机。
2、大家如果发现问题,请告知于我,谢谢。



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马