├── .classpath
├── .gitignore
├── .project
├── LICENSE
├── README.md
├── minicap
└── shared
│ ├── android-10
│ └── armeabi-v7a
│ │ └── minicap.so
│ ├── android-14
│ ├── armeabi-v7a
│ │ └── minicap.so
│ └── x86
│ │ └── minicap.so
│ ├── android-15
│ ├── armeabi-v7a
│ │ └── minicap.so
│ └── x86
│ │ └── minicap.so
│ ├── android-16
│ ├── armeabi-v7a
│ │ └── minicap.so
│ └── x86
│ │ └── minicap.so
│ ├── android-17
│ ├── armeabi-v7a
│ │ └── minicap.so
│ └── x86
│ │ └── minicap.so
│ ├── android-18
│ ├── armeabi-v7a
│ │ └── minicap.so
│ └── x86
│ │ └── minicap.so
│ ├── android-19
│ ├── armeabi-v7a
│ │ └── minicap.so
│ └── x86
│ │ └── minicap.so
│ ├── android-21
│ ├── arm64-v8a
│ │ └── minicap.so
│ ├── armeabi-v7a
│ │ └── minicap.so
│ ├── x86
│ │ └── minicap.so
│ └── x86_64
│ │ └── minicap.so
│ ├── android-22
│ ├── arm64-v8a
│ │ └── minicap.so
│ ├── armeabi-v7a
│ │ └── minicap.so
│ ├── x86
│ │ └── minicap.so
│ └── x86_64
│ │ └── minicap.so
│ ├── android-23
│ ├── arm64-v8a
│ │ └── minicap.so
│ ├── armeabi-v7a
│ │ └── minicap.so
│ ├── x86
│ │ └── minicap.so
│ └── x86_64
│ │ └── minicap.so
│ ├── android-24
│ ├── arm64-v8a
│ │ └── minicap.so
│ ├── armeabi-v7a
│ │ └── minicap.so
│ ├── x86
│ │ └── minicap.so
│ └── x86_64
│ │ └── minicap.so
│ ├── android-25
│ ├── arm64-v8a
│ │ └── minicap.so
│ ├── armeabi-v7a
│ │ └── minicap.so
│ ├── x86
│ │ └── minicap.so
│ └── x86_64
│ │ └── minicap.so
│ ├── android-26
│ ├── arm64-v8a
│ │ └── minicap.so
│ ├── armeabi-v7a
│ │ └── minicap.so
│ ├── x86
│ │ └── minicap.so
│ └── x86_64
│ │ └── minicap.so
│ ├── android-27
│ ├── arm64-v8a
│ │ └── minicap.so
│ ├── armeabi-v7a
│ │ └── minicap.so
│ ├── x86
│ │ └── minicap.so
│ └── x86_64
│ │ └── minicap.so
│ └── android-9
│ └── armeabi-v7a
│ └── minicap.so
├── minitouch
├── arm64-v8a
│ ├── minitouch
│ └── minitouch-nopie
├── armeabi-v7a
│ ├── minitouch
│ └── minitouch-nopie
├── armeabi
│ ├── minitouch
│ └── minitouch-nopie
├── mips
│ ├── minitouch
│ └── minitouch-nopie
├── mips64
│ ├── minitouch
│ └── minitouch-nopie
├── x86
│ ├── minitouch
│ └── minitouch-nopie
└── x86_64
│ ├── minitouch
│ └── minitouch-nopie
├── screenshot.jpg
└── src
└── com
└── company
├── devices
└── ADB.java
├── gui
└── MinicapFrame.java
├── minicap
├── AndroidScreenObserver.java
├── Banner.java
├── MiniCapUtil.java
└── ScreenSubject.java
├── minitouch
└── MiniTouchUtils.java
└── utils
├── Constant.java
└── TimeUtil.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | MiniCapAndMiniTouch
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MiniCapAndMiniTouch
2 | ## 功能
3 | 1. 时间实时显示手机界面
4 | 2. 投屏的操作(单击、拖动,滑动)支持
5 | ## 配置
6 | 1. ADB类下需要配置adb的路径
7 |
8 | ## 接下来计划
9 | 1. 实现软键盘的输入
--------------------------------------------------------------------------------
/minicap/shared/android-10/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-10/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-14/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-14/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-14/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-14/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-15/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-15/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-15/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-15/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-16/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-16/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-16/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-16/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-17/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-17/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-17/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-17/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-18/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-18/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-18/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-18/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-19/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-19/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-19/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-19/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-21/arm64-v8a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-21/arm64-v8a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-21/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-21/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-21/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-21/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-21/x86_64/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-21/x86_64/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-22/arm64-v8a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-22/arm64-v8a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-22/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-22/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-22/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-22/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-22/x86_64/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-22/x86_64/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-23/arm64-v8a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-23/arm64-v8a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-23/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-23/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-23/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-23/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-23/x86_64/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-23/x86_64/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-24/arm64-v8a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-24/arm64-v8a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-24/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-24/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-24/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-24/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-24/x86_64/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-24/x86_64/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-25/arm64-v8a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-25/arm64-v8a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-25/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-25/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-25/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-25/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-25/x86_64/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-25/x86_64/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-26/arm64-v8a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-26/arm64-v8a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-26/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-26/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-26/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-26/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-26/x86_64/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-26/x86_64/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-27/arm64-v8a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-27/arm64-v8a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-27/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-27/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-27/x86/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-27/x86/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-27/x86_64/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-27/x86_64/minicap.so
--------------------------------------------------------------------------------
/minicap/shared/android-9/armeabi-v7a/minicap.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minicap/shared/android-9/armeabi-v7a/minicap.so
--------------------------------------------------------------------------------
/minitouch/arm64-v8a/minitouch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/arm64-v8a/minitouch
--------------------------------------------------------------------------------
/minitouch/arm64-v8a/minitouch-nopie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/arm64-v8a/minitouch-nopie
--------------------------------------------------------------------------------
/minitouch/armeabi-v7a/minitouch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/armeabi-v7a/minitouch
--------------------------------------------------------------------------------
/minitouch/armeabi-v7a/minitouch-nopie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/armeabi-v7a/minitouch-nopie
--------------------------------------------------------------------------------
/minitouch/armeabi/minitouch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/armeabi/minitouch
--------------------------------------------------------------------------------
/minitouch/armeabi/minitouch-nopie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/armeabi/minitouch-nopie
--------------------------------------------------------------------------------
/minitouch/mips/minitouch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/mips/minitouch
--------------------------------------------------------------------------------
/minitouch/mips/minitouch-nopie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/mips/minitouch-nopie
--------------------------------------------------------------------------------
/minitouch/mips64/minitouch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/mips64/minitouch
--------------------------------------------------------------------------------
/minitouch/mips64/minitouch-nopie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/mips64/minitouch-nopie
--------------------------------------------------------------------------------
/minitouch/x86/minitouch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/x86/minitouch
--------------------------------------------------------------------------------
/minitouch/x86/minitouch-nopie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/x86/minitouch-nopie
--------------------------------------------------------------------------------
/minitouch/x86_64/minitouch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/x86_64/minitouch
--------------------------------------------------------------------------------
/minitouch/x86_64/minitouch-nopie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/minitouch/x86_64/minitouch-nopie
--------------------------------------------------------------------------------
/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TMLAndroid/MiniCapAndMiniTouch/b4a31b582709fbff9aff02c44b54a9b630b1f28d/screenshot.jpg
--------------------------------------------------------------------------------
/src/com/company/devices/ADB.java:
--------------------------------------------------------------------------------
1 | package com.company.devices;
2 |
3 | import java.io.File;
4 |
5 | import com.android.ddmlib.AndroidDebugBridge;
6 | import com.android.ddmlib.IDevice;
7 |
8 |
9 | public class ADB {
10 |
11 | private AndroidDebugBridge mAndroidDebugBridge = null;
12 | private String adbPath = "/Users/tangminglong/Library/Android/sdk/platform-tools";
13 | private String adbPlatformTools = "platform-tools";
14 | public static boolean hasInitAdb = false;
15 |
16 | public ADB(){
17 | init();
18 | }
19 |
20 | /**
21 | * 获取系统adb路径
22 | * @return
23 | */
24 | private String getADBPath(){
25 | if (adbPath == null){
26 | adbPath = System.getenv("ANDROID_HOME");
27 | if(adbPath != null){
28 | adbPath += File.separator + adbPlatformTools;
29 | }else {
30 | return null;
31 | }
32 | }
33 | adbPath += File.separator + "adb";
34 | return adbPath;
35 | }
36 |
37 | /**
38 | * 初始化adb连接
39 | * @return
40 | */
41 | private boolean init() {
42 | boolean success = false;
43 | if (!hasInitAdb){
44 | String adbPath = getADBPath();
45 | if (adbPath != null) {
46 | AndroidDebugBridge.init(false);
47 | mAndroidDebugBridge = AndroidDebugBridge.createBridge(adbPath, true);
48 | if (mAndroidDebugBridge != null) {
49 | success = true;
50 | hasInitAdb = true;
51 | }
52 | // 延时处理adb获取设备信息
53 | if (success) {
54 | int loopCount = 0;
55 | while (mAndroidDebugBridge.hasInitialDeviceList() == false) {
56 | try {
57 | Thread.sleep(100);
58 | loopCount++;
59 | } catch (InterruptedException e) {
60 | }
61 | if (loopCount > 100) {
62 | success = false;
63 | break;
64 | }
65 | }
66 | }
67 | }
68 | }
69 |
70 | return success;
71 | }
72 |
73 | // 获取连接的设备列表
74 | public IDevice[] getDevices() {
75 | IDevice[] devicelist = null;
76 | if (mAndroidDebugBridge != null) {
77 | devicelist = mAndroidDebugBridge.getDevices();
78 | }
79 | return devicelist;
80 | }
81 | }
--------------------------------------------------------------------------------
/src/com/company/gui/MinicapFrame.java:
--------------------------------------------------------------------------------
1 | package com.company.gui;
2 |
3 | import com.android.ddmlib.AdbCommandRejectedException;
4 | import com.android.ddmlib.CollectingOutputReceiver;
5 | import com.android.ddmlib.IDevice;
6 | import com.android.ddmlib.IDevice.DeviceState;
7 | import com.android.ddmlib.ShellCommandUnresponsiveException;
8 | import com.android.ddmlib.TimeoutException;
9 | import com.company.devices.ADB;
10 | import com.company.minicap.AndroidScreenObserver;
11 | import com.company.minicap.Banner;
12 | import com.company.minicap.MiniCapUtil;
13 | import com.company.minitouch.MiniTouchUtils;
14 | import org.apache.log4j.Logger;
15 |
16 | import javax.swing.*;
17 | import javax.swing.event.DocumentEvent;
18 | import javax.swing.event.DocumentListener;
19 |
20 | import java.awt.*;
21 | import java.awt.event.*;
22 | import java.awt.image.BufferedImage;
23 | import java.io.BufferedReader;
24 | import java.io.BufferedWriter;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.io.InputStreamReader;
28 | import java.io.OutputStream;
29 | import java.net.Socket;
30 | import java.util.Scanner;
31 |
32 |
33 | public class MinicapFrame extends JFrame {
34 |
35 | private static final Logger LOG = Logger.getLogger("PageTest.class");
36 |
37 | private MyPanel mp = null;
38 | private IDevice device;
39 | private int width = 360;
40 | private int height = 640;
41 | private Thread thread = null;
42 | private Socket socket;
43 | private Banner banner = new Banner();
44 | private OutputStream outputStream = null;
45 |
46 | public static String encode(String str) {
47 | String prifix = "\\u";
48 | StringBuffer unicode = new StringBuffer();
49 | for (int i = 0; i < str.length(); i++) {
50 | char c = str.charAt(i);
51 | String code = prifix + format(Integer.toHexString(c));
52 | unicode.append(code);
53 | }
54 | return unicode.toString();
55 | }
56 |
57 |
58 | /**
59 | * 为长度不足4位的unicode 值补零
60 | * @param str
61 | * @return
62 | */
63 | private static String format(String str) {
64 | for ( int i=0, l=4-str.length(); i dataQueue = new LinkedBlockingQueue();
43 | private List observers = new ArrayList();
44 |
45 | private Banner banner = new Banner();
46 | private static final int CAP_PORT = 1717;
47 | private static final int TOUCH_PORT = 1111;
48 | private Socket socket;
49 | private IDevice device;
50 | private String REMOTE_PATH = "/data/local/tmp";
51 | private String ABI_COMMAND = "ro.product.cpu.abi";
52 | private String SDK_COMMAND = "ro.build.version.sdk";
53 | private String MINICAP_BIN = "minicap";
54 | private String MINITOUCH_BIN = "minitouch";
55 | private String MINICAP_NOPIE = "minicap-nopie";
56 | private String MINICAP_FILE = "";
57 | private String MINITOUCH_NOPIE = "minitouch-nopie";
58 | private String MINITOUCH_FILE = "";
59 |
60 | private String MINICAP_SO = "minicap.so";
61 | private String MINICAP_CHMOD_COMMAND = "chmod 777 %s/%s";
62 | private String MINICAP_WM_SIZE_COMMAND = "wm size";
63 | private String MINICAP_START_COMMAND = "LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/%s -P %s@%s/0";
64 | private String MINITOUCH_START_COMMAND = "/data/local/tmp/%s";
65 | private String MINICAP_TAKESCREENSHOT_COMMAND = "LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/%s -P %s@%s/0 -s >%s";
66 | private String ADB_PULL_COMMAND = " adb -s %s pull %s %s";
67 |
68 |
69 | private boolean isRunning = false;
70 | private String size;
71 |
72 | public MiniCapUtil(IDevice device) {
73 | this.device = device;
74 | init();
75 | }
76 | //判断是否支持minicap
77 | public boolean isSupoort(){
78 | String supportCommand = String.format("LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P %s@%s/0 -t", size,size);
79 | String output = executeShellCommand(supportCommand);
80 | if(output.trim().endsWith("OK")){
81 | return true;
82 | }
83 | return false;
84 | }
85 |
86 | /**
87 | * 将minicap的二进制和.so文件push到/data/local/tmp文件夹下,启动minicap服务
88 | */
89 | private void init() {
90 |
91 | String abi = null;
92 | while (abi==null){
93 | abi = device.getProperty(ABI_COMMAND);
94 | System.out.println(abi);
95 | }
96 |
97 | String sdk = device.getProperty(SDK_COMMAND);
98 | if (Integer.valueOf(sdk) < 16) {
99 | MINITOUCH_FILE = MINITOUCH_NOPIE;
100 | MINICAP_FILE = MINICAP_NOPIE;
101 | }else {
102 | MINITOUCH_FILE = MINITOUCH_BIN;
103 | MINICAP_FILE = MINICAP_BIN;
104 | }
105 | System.out.println("获取abi 信息以及系统的sdk为abi:"+abi+"sdk:"+sdk);
106 | File minicapBinFile = new File(Constant.getMinicapBin(), abi
107 | + File.separator + MINICAP_FILE);
108 | File minitouchBinFile = new File(Constant.getMiniTouchBin(), abi
109 | + File.separator + MINITOUCH_FILE);
110 | File minicapSoFile = new File(Constant.getMinicapSo(), "android-" + sdk
111 | + File.separator + abi + File.separator + MINICAP_SO);
112 | System.out.println(minicapSoFile.getAbsolutePath());
113 | try {
114 | // 将minicap的可执行文件和.so文件一起push到设备中
115 | device.pushFile(minicapBinFile.getAbsolutePath(), REMOTE_PATH
116 | + File.separator + MINICAP_FILE);
117 | device.pushFile(minitouchBinFile.getAbsolutePath(), REMOTE_PATH
118 | + File.separator + MINITOUCH_FILE);
119 | device.pushFile(minicapSoFile.getAbsolutePath(), REMOTE_PATH
120 | + File.separator + MINICAP_SO);
121 | executeShellCommand(String.format(MINICAP_CHMOD_COMMAND,
122 | REMOTE_PATH, MINICAP_FILE));
123 | executeShellCommand(String.format(MINICAP_CHMOD_COMMAND,
124 | REMOTE_PATH, MINITOUCH_FILE));
125 | // 端口转发
126 | device.createForward(CAP_PORT, "minicap",
127 | DeviceUnixSocketNamespace.ABSTRACT);
128 |
129 | // 端口转发
130 | device.createForward(TOUCH_PORT, "minitouch",
131 | DeviceUnixSocketNamespace.ABSTRACT);
132 |
133 | // 获取设备屏幕的尺寸
134 | String output = executeShellCommand(MINICAP_WM_SIZE_COMMAND);
135 | size = output.split(":")[1].trim();
136 |
137 | } catch (SyncException e) {
138 | // TODO Auto-generated catch block
139 | e.printStackTrace();
140 | } catch (IOException e) {
141 | // TODO Auto-generated catch block
142 | e.printStackTrace();
143 | } catch (AdbCommandRejectedException e) {
144 | // TODO Auto-generated catch block
145 | e.printStackTrace();
146 | } catch (TimeoutException e) {
147 | // TODO Auto-generated catch block
148 | e.printStackTrace();
149 | }
150 | }
151 |
152 | public void takeScreenShotOnce() {
153 | String savePath = "/data/local/tmp/screenshot.jpg";
154 | String takeScreenShotCommand = String.format(
155 | MINICAP_TAKESCREENSHOT_COMMAND, MINICAP_FILE,size,
156 | size, savePath);
157 | String localPath = System.getProperty("user.dir") + "/screenshot.jpg";
158 | String pullCommand = String.format(ADB_PULL_COMMAND,
159 | device.getSerialNumber(), savePath, localPath);
160 | try {
161 | // Process process =
162 | // Runtime.getRuntime().exec(takeScreenShotCommand);
163 | executeShellCommand(takeScreenShotCommand);
164 | device.pullFile(savePath, localPath);
165 | // BufferedReader br = new BufferedReader(new InputStreamReader(
166 | // process.getInputStream()));
167 | // String line = null;
168 | // while ((line = br.readLine()) != null) {
169 | // LOG.debug(line);
170 | // }
171 | // Thread.sleep(200);
172 | // process.waitFor();
173 |
174 | //Runtime.getRuntime().exec(pullCommand);
175 | } catch (IOException e) {
176 | // TODO Auto-generated catch block
177 | e.printStackTrace();
178 | } catch (SyncException e) {
179 | // TODO Auto-generated catch block
180 | e.printStackTrace();
181 | } catch (AdbCommandRejectedException e) {
182 | // TODO Auto-generated catch block
183 | e.printStackTrace();
184 | } catch (TimeoutException e) {
185 | // TODO Auto-generated catch block
186 | e.printStackTrace();
187 | }
188 |
189 | }
190 |
191 | private static String bytesToHexString(byte[] src) {
192 | StringBuilder stringBuilder = new StringBuilder("");
193 | if (src == null || src.length <= 0) {
194 | return null;
195 | }
196 | for (int i = 0; i < src.length; i++) {
197 | int v = src[i] & 0xFF;
198 | String hv = Integer.toHexString(v);
199 | if (hv.length() < 2) {
200 | stringBuilder.append(0);
201 | }
202 | stringBuilder.append(hv + " ");
203 | }
204 | return stringBuilder.toString();
205 | }
206 |
207 | private String executeShellCommand(String command) {
208 | CollectingOutputReceiver output = new CollectingOutputReceiver();
209 | try {
210 | device.executeShellCommand(command, output, 0);
211 | } catch (TimeoutException e) {
212 | // TODO Auto-generated catch block
213 | e.printStackTrace();
214 | } catch (AdbCommandRejectedException e) {
215 | // TODO Auto-generated catch block
216 | e.printStackTrace();
217 | } catch (ShellCommandUnresponsiveException e) {
218 | // TODO Auto-generated catch block
219 | e.printStackTrace();
220 | } catch (IOException e) {
221 | // TODO Auto-generated catch block
222 | e.printStackTrace();
223 | }
224 | return output.getOutput();
225 | }
226 |
227 | public void startScreenListener() {
228 | isRunning = true;
229 | Thread frame = new Thread(new ImageBinaryFrameCollector());
230 | frame.start();
231 | Thread convert = new Thread(new ImageConverter());
232 | convert.start();
233 | Thread touch = new Thread(new TouchThread());
234 | touch.start();
235 |
236 |
237 | // new Thread(new Runnable() {
238 | //
239 | // @Override
240 | // public void run() {
241 | // // TODO Auto-generated method stub
242 | // //Scanner sc = new Scanner(System.in);
243 | // //利用hasNextXXX()判断是否还有下一输入项
244 | // while (true) {
245 | //
246 | // //利用nextXXX()方法输出内容
247 | // // String str = sc.next();
248 | // String str ="你我";
249 | // str = encode(str);
250 | //
251 | //
252 | // String result = "am broadcast -a ADB_INPUT_TEXT --es msg \'"+str+"\'";
253 | //
254 | //
255 | // System.out.println(":"+str);
256 | // executeShellCommand(result);
257 | //
258 | // }
259 | // }
260 | // }).start();
261 | }
262 |
263 |
264 | public static String encode(String str) {
265 | String prifix = "\\u";
266 | StringBuffer unicode = new StringBuffer();
267 | for (int i = 0; i < str.length(); i++) {
268 | char c = str.charAt(i);
269 | String code = prifix + format(Integer.toHexString(c));
270 | unicode.append(code);
271 | }
272 | return unicode.toString();
273 | }
274 |
275 |
276 | /**
277 | * 为长度不足4位的unicode 值补零
278 | * @param str
279 | * @return
280 | */
281 | private static String format(String str) {
282 | for ( int i=0, l=4-str.length(); i= 0) {
375 | buffer = subByteArray(buffer, 0, realLen);
376 |
377 | }
378 | if(realLen >= 0) {
379 | dataQueue.add(buffer);
380 | }
381 |
382 | }
383 | } catch (IOException e) {
384 | e.printStackTrace();
385 | } finally {
386 | if (socket != null && socket.isConnected()) {
387 | try {
388 | socket.close();
389 | } catch (IOException e) {
390 | e.printStackTrace();
391 | }
392 | }
393 | if (stream != null) {
394 | try {
395 | stream.close();
396 | } catch (IOException e) {
397 | // TODO Auto-generated catch block
398 | e.printStackTrace();
399 | }
400 | }
401 | }
402 |
403 | LOG.debug("图片二进制数据收集器已关闭");
404 | }
405 |
406 | }
407 |
408 |
409 | class TouchThread implements Runnable {
410 | @Override
411 | public void run() {
412 | String startCmd = String.format(MINITOUCH_START_COMMAND,MINITOUCH_FILE);
413 | System.out.println(startCmd);
414 | executeShellCommand(startCmd);
415 | }
416 | }
417 |
418 |
419 | class ImageConverter implements Runnable {
420 | private int readBannerBytes = 0;
421 | private int bannerLength = 2;//头的长度
422 | private int readFrameBytes = 0;//已读byte长度
423 | private int frameBodyLength = 0;//图片的byte长度
424 | private byte[] frameBody = new byte[0];
425 |
426 | /*
427 | * (non-Javadoc)
428 | *
429 | * @see java.lang.Runnable#run()
430 | */
431 | public void run() {
432 | // TODO Auto-generated method stub
433 | long start = System.currentTimeMillis();
434 | while (isRunning) {
435 | if (dataQueue.isEmpty()) {
436 | // LOG.info("数据队列为空");
437 | continue;
438 | }
439 | byte[] buffer = dataQueue.poll();
440 | int len = buffer.length;
441 | System.out.println("长度:"+len);
442 | for (int cursor = 0; cursor < len;) {
443 | int byte10 = buffer[cursor] & 0xff;
444 | if (readBannerBytes < bannerLength) {//第一次进来读取头部信息
445 | cursor = parserBanner(cursor, byte10);
446 | } else if (readFrameBytes < 4) {//读取并设置图片的大小
447 | // 第二次的缓冲区中前4位数字和为frame的缓冲区大小
448 | frameBodyLength += (byte10 << (readFrameBytes * 8)) >>> 0;
449 | cursor += 1;
450 | readFrameBytes += 1;
451 | // LOG.debug("解析图片大小 = " + readFrameBytes);
452 | } else {
453 |
454 | System.out.println("len:"+len+"cursor:"+cursor+"frameBodyLength:"+frameBodyLength);
455 | if (len - cursor >= frameBodyLength) {
456 | LOG.debug("frameBodyLength = " + frameBodyLength);
457 | byte[] subByte = subByteArray(buffer, cursor,
458 | cursor + frameBodyLength);
459 | frameBody = byteMerger(frameBody, subByte);
460 | if ((frameBody[0] != -1) || frameBody[1] != -40) {
461 | LOG.error(String
462 | .format("Frame body does not start with JPG header"));
463 | return;
464 | }
465 |
466 | System.out.println("JPG头: "+frameBody[0]+","+frameBody[1]);
467 | final byte[] finalBytes = subByteArray(frameBody,
468 | 0, frameBody.length);
469 | // 转化成bufferImage
470 | new Thread(new Runnable() {
471 |
472 | @Override
473 | public void run() {
474 | // TODO Auto-generated method stub
475 | Image image = createImageFromByte(finalBytes);
476 | notifyObservers(image);
477 | }
478 | }).start();
479 |
480 | long current = System.currentTimeMillis();
481 |
482 | System.out.println("图片已生成,耗时: "
483 | + TimeUtil.formatElapsedTime(current
484 | - start));
485 | start = current;
486 | cursor += frameBodyLength;
487 | restore();
488 | } else {
489 | System.out.println("所需数据大小 : " + frameBodyLength);
490 | byte[] subByte = subByteArray(buffer, cursor, len);
491 | frameBody = byteMerger(frameBody, subByte);
492 | frameBodyLength -= (len - cursor);
493 | readFrameBytes += (len - cursor);
494 | cursor = len;
495 | }
496 | }
497 | }
498 | }
499 |
500 | }
501 |
502 | private void restore() {
503 | frameBodyLength = 0;
504 | readFrameBytes = 0;
505 | frameBody = new byte[0];
506 | }
507 |
508 | private int parserBanner(int cursor, int byte10) {
509 | switch (readBannerBytes) {
510 | case 0:
511 | // version
512 | banner.setVersion(byte10);
513 | break;
514 | case 1:
515 | // length
516 | bannerLength = byte10;
517 | banner.setLength(byte10);
518 | break;
519 | case 2:
520 | case 3:
521 | case 4:
522 | case 5:
523 | // pid
524 | int pid = banner.getPid();
525 | pid += (byte10 << ((readBannerBytes - 2) * 8)) >>> 0;
526 | banner.setPid(pid);
527 | break;
528 | case 6:
529 | case 7:
530 | case 8:
531 | case 9:
532 | // real width
533 | int realWidth = banner.getReadWidth();
534 | System.out.println("realwidth0"+realWidth);
535 | realWidth += (byte10 << ((readBannerBytes - 6) * 8)) >>> 0;
536 | System.out.println("realwidth1"+realWidth);
537 | banner.setReadWidth(realWidth);
538 | break;
539 | case 10:
540 | case 11:
541 | case 12:
542 | case 13:
543 | // real height
544 | int realHeight = banner.getReadHeight();
545 | realHeight += (byte10 << ((readBannerBytes - 10) * 8)) >>> 0;
546 | banner.setReadHeight(realHeight);
547 | break;
548 | case 14:
549 | case 15:
550 | case 16:
551 | case 17:
552 | // virtual width
553 | int virtualWidth = banner.getVirtualWidth();
554 | virtualWidth += (byte10 << ((readBannerBytes - 14) * 8)) >>> 0;
555 | banner.setVirtualWidth(virtualWidth);
556 | System.out.println("virtual"+virtualWidth);
557 | break;
558 | case 18:
559 | case 19:
560 | case 20:
561 | case 21:
562 | // virtual height
563 | int virtualHeight = banner.getVirtualHeight();
564 | virtualHeight += (byte10 << ((readBannerBytes - 18) * 8)) >>> 0;
565 | banner.setVirtualHeight(virtualHeight);
566 | System.out.println("virtualhegith"+virtualHeight);
567 | break;
568 | case 22:
569 | // orientation
570 | banner.setOrientation(byte10 * 90);
571 | break;
572 | case 23:
573 | // quirks
574 | banner.setQuirks(byte10);
575 | break;
576 | }
577 |
578 | cursor += 1;
579 | readBannerBytes += 1;
580 |
581 | if (readBannerBytes == bannerLength) {
582 | LOG.debug(banner.toString());
583 | }
584 | return cursor;
585 | }
586 |
587 | }
588 |
589 | /*
590 | * (non-Javadoc)
591 | *
592 | * @see
593 | * com.wuba.utils.screenshot.ScreenSubject#registerObserver(com.wuba.utils
594 | * .screenshot.AndroidScreenObserver)
595 | */
596 | public void registerObserver(AndroidScreenObserver o) {
597 | // TODO Auto-generated method stub
598 | observers.add(o);
599 |
600 | }
601 |
602 | /*
603 | * (non-Javadoc)
604 | *
605 | * @see
606 | * com.wuba.utils.screenshot.ScreenSubject#removeObserver(com.wuba.utils
607 | * .screenshot.AndroidScreenObserver)
608 | */
609 | public void removeObserver(AndroidScreenObserver o) {
610 | // TODO Auto-generated method stub
611 | int index = observers.indexOf(o);
612 | if (index != -1) {
613 | observers.remove(o);
614 | }
615 | }
616 |
617 | /*
618 | * (non-Javadoc)
619 | *
620 | * @see com.wuba.minicap.ScreenSubject#notifyObservers(java.awt.Image)
621 | */
622 | @Override
623 | public void notifyObservers(Image image) {
624 | for (AndroidScreenObserver observer : observers) {
625 | observer.frameImageChange(image);
626 | }
627 | // TODO Auto-generated method stub
628 |
629 | }
630 | }
631 |
--------------------------------------------------------------------------------
/src/com/company/minicap/ScreenSubject.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.company.minicap;
5 |
6 | import java.awt.Image;
7 |
8 |
9 |
10 | public interface ScreenSubject {
11 | public void registerObserver(AndroidScreenObserver o);
12 |
13 | public void removeObserver(AndroidScreenObserver o);
14 |
15 | public void notifyObservers(Image image);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/com/company/minitouch/MiniTouchUtils.java:
--------------------------------------------------------------------------------
1 | package com.company.minitouch;
2 |
3 | import com.android.ddmlib.*;
4 | import com.company.utils.Constant;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 |
9 |
10 | public class MiniTouchUtils {
11 |
12 | private IDevice device;
13 | private static final int PORT = 1111;
14 | private String ABI_COMMAND = "ro.product.cpu.abi";
15 | private String SDK_COMMAND = "ro.build.version.sdk";
16 | private String MINITOUCH_BIN = "minitouch";
17 | private String REMOTE_PATH = "/data/local/tmp";
18 | private String MINICAP_CHMOD_COMMAND = "chmod 777 %s/%s";
19 | private String MINICAP_WM_SIZE_COMMAND = "wm size";
20 | private String MINICAP_START_COMMAND = "LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P %s@%s/0";
21 | private String MINICAP_TAKESCREENSHOT_COMMAND = "LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P %s@%s/0 -s >%s";
22 | private String ADB_PULL_COMMAND = "adb -s %s pull %s %s";
23 | public MiniTouchUtils(IDevice device) {
24 | this.device = device;
25 | init();
26 | }
27 |
28 |
29 |
30 | /**
31 | * 将minicap的二进制和.so文件push到/data/local/tmp文件夹下,启动minicap服务
32 | */
33 | private void init() {
34 |
35 | String abi = device.getProperty(ABI_COMMAND);
36 | String sdk = device.getProperty(SDK_COMMAND);
37 | System.out.println("minitouch获取abi 信息以及系统的sdk为abi:"+abi+"sdk:"+sdk);
38 | File miniTouchBinFile = new File(Constant.getMiniTouchBin(), abi
39 | + File.separator + MINITOUCH_BIN);
40 | try {
41 | // 将minicap的可执行文件和.so文件一起push到设备中
42 | System.out.println(miniTouchBinFile.getAbsolutePath()+","+REMOTE_PATH
43 | + File.separator + MINITOUCH_BIN);
44 | device.pushFile(miniTouchBinFile.getAbsolutePath(), REMOTE_PATH
45 | + File.separator + MINITOUCH_BIN);
46 | executeShellCommand(String.format(MINICAP_CHMOD_COMMAND,
47 | REMOTE_PATH, MINITOUCH_BIN));
48 | // 端口转发
49 | device.createForward(PORT, "minitouch",
50 | IDevice.DeviceUnixSocketNamespace.ABSTRACT);
51 |
52 |
53 | } catch (SyncException e) {
54 | // TODO Auto-generated catch block
55 | e.printStackTrace();
56 | } catch (IOException e) {
57 | // TODO Auto-generated catch block
58 | e.printStackTrace();
59 | } catch (AdbCommandRejectedException e) {
60 | // TODO Auto-generated catch block
61 | e.printStackTrace();
62 | } catch (TimeoutException e) {
63 | // TODO Auto-generated catch block
64 | e.printStackTrace();
65 | }
66 | }
67 |
68 | private String executeShellCommand(String command) {
69 | CollectingOutputReceiver output = new CollectingOutputReceiver();
70 | try {
71 | device.executeShellCommand(command, output, 0);
72 | } catch (TimeoutException e) {
73 | // TODO Auto-generated catch block
74 | e.printStackTrace();
75 | } catch (AdbCommandRejectedException e) {
76 | // TODO Auto-generated catch block
77 | e.printStackTrace();
78 | } catch (ShellCommandUnresponsiveException e) {
79 | // TODO Auto-generated catch block
80 | e.printStackTrace();
81 | } catch (IOException e) {
82 | // TODO Auto-generated catch block
83 | e.printStackTrace();
84 | }
85 | return output.getOutput();
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/com/company/utils/Constant.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.company.utils;
5 |
6 | import java.io.File;
7 |
8 |
9 | public class Constant {
10 | private static final String ROOT = System.getProperty("user.dir");
11 |
12 | public static File getMinicap() {
13 | return new File(ROOT, "minicap");
14 | }
15 |
16 | public static File getMinicapBin() {
17 | return new File(ROOT, "minicap/bin");
18 | }
19 |
20 | public static File getMiniTouchBin() {
21 | return new File(ROOT, "minitouch");
22 | }
23 |
24 | public static File getMinicapSo() {
25 | return new File(ROOT, "minicap/shared");
26 | }
27 |
28 | public static File getMinicapAdb() {
29 | return new File(ROOT, "platform-tools");
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/company/utils/TimeUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.company.utils;
17 |
18 | import java.text.SimpleDateFormat;
19 | import java.util.Date;
20 | import java.util.TimeZone;
21 | import java.util.concurrent.TimeUnit;
22 |
23 | /**
24 | * Contains time related utility methods.
25 | */
26 | public class TimeUtil {
27 |
28 | private final static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
29 | private final static SimpleDateFormat TIME_FORMAT_MSEC = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
30 | private final static SimpleDateFormat FILE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
31 |
32 | // only static methods, don't allow construction
33 | private TimeUtil() {
34 | }
35 |
36 | /**
37 | * Return a prettified version of the given elapsed time in milliseconds.
38 | */
39 | public static synchronized String formatElapsedTime(long elapsedTimeMs) {
40 | if (elapsedTimeMs < 1000) {
41 | return String.format("%d ms", elapsedTimeMs);
42 | }
43 | long seconds = TimeUnit.MILLISECONDS.toSeconds(elapsedTimeMs) % 60;
44 | long minutes = TimeUnit.MILLISECONDS.toMinutes(elapsedTimeMs) % 60;
45 | long hours = TimeUnit.MILLISECONDS.toHours(elapsedTimeMs);
46 | StringBuilder time = new StringBuilder();
47 | if (hours > 0) {
48 | time.append(hours);
49 | time.append("h ");
50 | }
51 | if (minutes > 0) {
52 | time.append(minutes);
53 | time.append("m ");
54 | }
55 | time.append(seconds);
56 | time.append("s");
57 |
58 | return time.toString();
59 | }
60 |
61 | /**
62 | * Return a readable formatted version of the given epoch time.
63 | *
64 | * @param epochTime the epoch time in milliseconds
65 | * @return a user readable string
66 | */
67 | public static synchronized String formatTimeStamp(long epochTime) {
68 | return TIME_FORMAT.format(new Date(epochTime));
69 | }
70 |
71 | public static String getTimestamp() {
72 | return formatTimeStamp(System.currentTimeMillis());
73 | }
74 |
75 | public static synchronized String formatTimeStampMsec(long epochTime) {
76 | return TIME_FORMAT_MSEC.format(new Date(epochTime));
77 | }
78 |
79 | public static String getTimestampMsec() {
80 | return formatTimeStampMsec(System.currentTimeMillis());
81 | }
82 |
83 | public static synchronized String formatTimeForFile(long epochTime) {
84 | return FILE_TIME_FORMAT.format(new Date(epochTime));
85 | }
86 |
87 | public static String getTimestampForFile() {
88 | return formatTimeForFile(System.currentTimeMillis());
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------