Skip to content

Commit b1d5a9d

Browse files
committed
Added takeSnapshot() functionality
- Version 4.2.0 - PyDev project interpreter set to python 2.7 - Added screenshot examples - Added PIL dependency for snapshot Images
1 parent a7cfb14 commit b1d5a9d

File tree

7 files changed

+107
-11
lines changed

7 files changed

+107
-11
lines changed

AndroidViewClient/.pydevproject

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<?eclipse-pydev version="1.0"?>
33

44
<pydev_project>
5-
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
5+
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">python 2.7</pydev_property>
66
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
77
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
88
<path>/AndroidViewClient/src</path>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#! /usr/bin/env monkeyrunner
2+
'''
3+
Copyright (C) 2012 Diego Torres Milano
4+
Created on Set 5, 2013
5+
6+
@author: diego
7+
'''
8+
9+
10+
import sys
11+
import os
12+
13+
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
14+
15+
if len(sys.argv) < 2:
16+
print >> sys.stderr, "usage: %s filename.png [serialno]" % sys.argv[0]
17+
sys.exit(1)
18+
19+
filename = sys.argv.pop(1)
20+
device = MonkeyRunner.waitForConnection()
21+
device.takeSnapshot().writeToFile(filename, 'PNG')
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#! /usr/bin/env python
2+
'''
3+
Copyright (C) 2012 Diego Torres Milano
4+
Created on Aug 31, 2013
5+
6+
@author: diego
7+
'''
8+
9+
10+
import sys
11+
import os
12+
13+
from com.dtmilano.android.viewclient import ViewClient
14+
15+
if len(sys.argv) < 2:
16+
sys.exit("usage: %s filename.png [serialno]" % sys.argv[0])
17+
18+
filename = sys.argv.pop(1)
19+
device, serialno = ViewClient.connectToDeviceOrExit(verbose=False)
20+
device.takeSnapshot().save(filename, 'PNG')

AndroidViewClient/src/com/dtmilano/android/adb/adbclient.py

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
'''
2+
Copyright (C) 2012-2013 Diego Torres Milano
23
Created on Dec 1, 2012
34
4-
@author: diego
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
@author: Diego Torres Milano
518
'''
19+
20+
__version__ = '4.2.0'
21+
622
import sys
723
import socket
824
import time
@@ -104,7 +120,7 @@ def __send(self, msg, checkok=True, reconnect=False):
104120
self.__setTransport()
105121
else:
106122
self.checkConnected()
107-
self.socket.send('%04x%s' % (len(msg), msg))
123+
self.socket.send('%04X%s' % (len(msg), msg))
108124
if checkok:
109125
self.__checkOk()
110126
if reconnect:
@@ -113,13 +129,23 @@ def __send(self, msg, checkok=True, reconnect=False):
113129
self.__connect()
114130
self.__setTransport()
115131

116-
def __receive(self):
132+
def __receive(self, nob=None):
117133
if DEBUG:
118134
print >> sys.stderr, "__receive()"
119135
self.checkConnected()
120-
n = int(self.socket.recv(4), 16)
121-
recv = self.socket.recv(n)
122-
return recv
136+
if nob is None:
137+
nob = int(self.socket.recv(4), 16)
138+
if DEBUG:
139+
print >> sys.stderr, " __receive: receiving", nob, "bytes"
140+
recv = bytearray()
141+
nr = 0
142+
while nr < nob:
143+
chunk = self.socket.recv(min((nob-nr), 4096))
144+
recv.extend(chunk)
145+
nr += len(chunk)
146+
if DEBUG:
147+
print >> sys.stderr, " __receive: returning len=", len(recv)
148+
return str(recv)
123149

124150
def __checkOk(self):
125151
if DEBUG:
@@ -221,7 +247,8 @@ def shell(self, cmd=None):
221247
return sout
222248

223249
def __getRestrictedScreen(self):
224-
''' Gets mRestrictedScreen values from dumpsys. This is a method to obtain display dimensions '''
250+
''' Gets C{mRestrictedScreen} values from dumpsys. This is a method to obtain display dimensions '''
251+
225252
rsRE = re.compile('\s*mRestrictedScreen=\((?P<x>\d+),(?P<y>\d+)\) (?P<w>\d+)x(?P<h>\d+)')
226253
for line in self.shell('dumpsys window').splitlines():
227254
m = rsRE.match(line)
@@ -278,6 +305,34 @@ def startActivity(self, component=None, flags=None, uri=None):
278305
cmd += ' %s' % uri
279306
self.shell(cmd)
280307

308+
def takeSnapshot(self, reconnect=False):
309+
try:
310+
from PIL import Image
311+
except:
312+
raise Exception("You have to install PIL to use takeSnapshot()")
313+
self.__send('framebuffer:', checkok=True, reconnect=False)
314+
import struct
315+
#case 1: // version
316+
# return 12; // bpp, size, width, height, 4*(length, offset)
317+
received = self.__receive(1 * 4 + 12 * 4)
318+
(version, bpp, size, width, height, roffset, rlen, boffset, blen, goffset, glen, aoffset, alen) = struct.unpack('<' + 'L' * 13, received)
319+
mode = [None]*4
320+
mode[roffset/rlen] = 'R'
321+
mode[boffset/blen] = 'B'
322+
mode[goffset/glen] = 'G'
323+
mode[aoffset/alen] = 'A'
324+
mode = ''.join(mode)
325+
if DEBUG:
326+
print >> sys.stderr, " takeSnapshot:", (version, bpp, size, width, height, roffset, rlen, boffset, blen, goffset, blen, aoffset, alen)
327+
self.__send('\0', checkok=False, reconnect=False)
328+
if DEBUG:
329+
print >> sys.stderr, " takeSnapshot: reading %d bytes" % (size)
330+
received = self.__receive(size)
331+
if reconnect:
332+
self.__connect()
333+
self.__setTransport()
334+
return Image.frombuffer(mode, (width, height), received, 'raw', mode, 0, 1)
335+
281336
def touch(self, x, y, eventType=DOWN_AND_UP):
282337
self.shell('input tap %d %d' % (x, y))
283338

AndroidViewClient/src/com/dtmilano/android/viewclient.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
@author: Diego Torres Milano
1919
'''
2020

21-
__version__ = '4.1.0'
21+
__version__ = '4.2.0'
2222

2323
import sys
2424
import subprocess

AndroidViewClient/tools/culebra

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ ___________________/ /__/ /__/ /__/ /________________________________
1818
1919
'''
2020

21-
__version__ = '4.1.0'
21+
__version__ = '4.2.0'
2222

2323
import re
2424
import sys

AndroidViewClient/tools/dump

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Created on Feb 3, 2012
66
@author: diego
77
'''
88

9-
__version__ = '4.1.0'
9+
__version__ = '4.2.0'
1010

1111
import sys
1212
import os

0 commit comments

Comments
 (0)