Android - How to access emulator screenshot via emulator? - android
My app allows the user to take a screenshot which it then sends to the server.
On a real device, the screenshots are saved at /storage/emulated/0/Pictures/Screenshots/ so that is fine.
But on the emulator, when I click the Take screenshot button (which is located in the panel beside the emulator), the screenshot is saved to my computer, but I can't find it anywhere in the emulator's file system - the /storage/emulated/0/Pictures/ directory exists, but the /storage/emulated/0/Pictures/Screenshots/ sub-directory does not.
Is there any way I can access the screenshot image on the emulator, or is there another way of taking the screenshot?
Emulate Volume Down + Power event to trigger Android's screenshot, then screenshot pictures will be stored at emulator's /storage/emulated/0/Pictures/Screenshots.
Here is the script. Run adb shell, then copy the code below and run, you should see the emulator start taking a screenshot.
cat > /data/local/tmp/screenshot.sh <<EOF
#!/bin/sh
echo 'volume key: down'
sendevent /dev/input/event1 1 114 1
echo 'power key: down'
sendevent /dev/input/event1 1 116 1
sendevent /dev/input/event1 0 0 0
sleep 1
echo 'volume key: up'
sendevent /dev/input/event1 1 114 0
echo 'power key: up'
sendevent /dev/input/event1 1 116 0
sendevent /dev/input/event1 0 0 0
EOF
sh /data/local/tmp/screenshot.sh
NOTE: My emulator's input device is "/dev/input/event1", this may be different for other devices. You can get the device info by running adb shell getevent command, then press the emulator's key, the output will be something like this(My Volume Down key, these are hex numbers, so 0x0072 is 114d):
/dev/input/event1: 0001 0072 00000001
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0072 00000000
/dev/input/event1: 0000 0000 00000000
It will save in your PC . You can also specify the location of screenshots from the emulator settings.
Please see the following image for reference.
Pretty old question, but you can use power menu:
Press and hold Power button
It will save in your device (PC), you can see the location from the emulator setting, click on more icon from right side of your emulator, and then click on setting
Use adb screencap command to your emulated device this should store the screen capture on the device itself allowing you to test your application.
Go to
Emulator settings > Settings > General > Screenshot save location >
'your file path'
then select your desire location to save your screenshot.
to find your taken screenshot you have to go your your file path which found by step 1.
hope its work.
This is how you can prevent the user from taking a screenshot and capturing the screen(Kotlin):
import android.view.WindowManager.LayoutParams
override fun onCreate(savedInstanceState: Bundle?) {
// ...
window.setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE)
// ...
}
Related
Cannot get mouse clicked coord on adb shell getevent
I have an Android TV box which I want to control it by ADB commands. Particularly, I want to send "tap" events on it. So far I've been doing it by "adb shell input tap x,y", which works fine but is sooo slow. So I'm trying to do it by "adb shell sendevent ..." which I think is faster. I've followed several tutorials on how to do this, but I'm facing the problem that I'm not able to record which is the event sequence in order to send a simple and single tap to my device. This is what I have done so far. In order to get the events sequence, I tried to get them with "getevent" command: q201:/ # getevent -l add device 1: /dev/input/event4 name: "HID 04b3:310b" could not get driver version for /dev/input/mouse1, Not a typewriter add device 2: /dev/input/event3 name: "cec_input" could not get driver version for /dev/input/mice, Not a typewriter add device 3: /dev/input/event2 name: "gpio_keypad" add device 4: /dev/input/event1 name: "adc_keypad" could not get driver version for /dev/input/mouse0, Not a typewriter add device 5: /dev/input/event0 name: "aml_keypad" When I click the mouse left button, then I see this event: /dev/input/event4: EV_MSC MSC_SCAN 00090001 /dev/input/event4: EV_KEY BTN_MOUSE DOWN /dev/input/event4: EV_SYN SYN_REPORT 00000000 /dev/input/event4: EV_MSC MSC_SCAN 00090001 /dev/input/event4: EV_KEY BTN_MOUSE UP /dev/input/event4: EV_SYN SYN_REPORT 00000000 No more events are generated. Each time I click the mouse, the same event is generated. Same codes. Same values. Always the same ! So ... where are the coords where I clicked?? Why I'm not getting any event regarding the position I'm clicking on? Actually, the click works on device, so .. where is the event? Without the event I won't be able to reproduce the click with the sendevent command. Thanks for your support! Gram
I finally used monkey (not monkeyrunner) to simulate taps. Much faster.
Fire a pinch in/out command to Android phone using adb
So far I'm able to tap, swipe, unlock, install/uninstall and launch app using adb commands but not able to find how to perform zoom in/out using adb command. I have got coordinates of pinch in/out but not understanding how to fire them using adb command from terminal. For example , we have command --> adb shell input tap x y So in this we can replace x and y with values/coordinates similarly I want to know the way to simulate pinch in/out. Coordinates that I get for pinch-in are below. {"id":0,"dumb":[{"events":[{"id":0,"pressure":1,"x":392.94117647058823,"y":607.4264705882354}],"action":0},{"events":[{"id":0,"pressure":1,"x":392.94117647058823,"y":607.4264705882354},{"id":1,"pressure":1,"x":327.05882352941177,"y":672.5735294117648}],"action":261},{"events":[{"id":0,"pressure":1,"x":392.94117647058823,"y":609.7794117647059},{"id":1,"pressure":1,"x":327.05882352941177,"y":670.2205882352941}],"action":2},{"events":[{"id":0,"pressure":1,"x":392.94117647058823,"y":612.1323529411765},{"id":1,"pressure":1,"x":327.05882352941177,"y":667.8676470588235}],"action":2},{"events":[{"id":0,"pressure":1,"x":392.94117647058823,"y":616.8382352941177},{"id":1,"pressure":1,"x":327.05882352941177,"y":663.1617647058823}],"action":2},{"events":[{"id":0,"pressure":1,"x":392.94117647058823,"y":626.25},{"id":1,"pressure":1,"x":327.05882352941177,"y":653.75}],"action":2},{"events":[{"id":0,"pressure":1,"x":392.94117647058823,"y":630.9558823529412},{"id":1,"pressure":1,"x":327.05882352941177,"y":649.0441176470589}],"action":2},{"events":[{"id":0,"pressure":1,"x":395.29411764705884,"y":635.6617647058823},{"id":1,"pressure":1,"x":324.70588235294116,"y":644.3382352941177}],"action":2},{"events":[{"id":0,"pressure":1,"x":397.64705882352945,"y":642.7205882352941},{"id":1,"pressure":1,"x":322.3529411764706,"y":637.2794117647059}],"action":2},{"events":[{"id":0,"pressure":1,"x":400,"y":649.7794117647059},{"id":1,"pressure":1,"x":320,"y":630.2205882352941}],"action":2},{"events":[{"id":0,"pressure":1,"x":402.3529411764706,"y":656.8382352941177},{"id":1,"pressure":1,"x":317.64705882352945,"y":623.1617647058823}],"action":2},{"events":[{"id":0,"pressure":1,"x":402.3529411764706,"y":661.5441176470589},{"id":1,"pressure":1,"x":317.64705882352945,"y":618.4558823529412}],"action":2},{"events":[{"id":0,"pressure":1,"x":404.7058823529412,"y":668.6029411764706},{"id":1,"pressure":1,"x":315.29411764705884,"y":611.3970588235294}],"action":2},{"events":[{"id":0,"pressure":1,"x":404.7058823529412,"y":673.3088235294118},{"id":1,"pressure":1,"x":315.29411764705884,"y":606.6911764705883}],"action":2},{"events":[{"id":0,"pressure":1,"x":404.7058823529412,"y":680.3676470588235},{"id":1,"pressure":1,"x":315.29411764705884,"y":599.6323529411765}],"action":2},{"events":[{"id":0,"pressure":1,"x":407.05882352941177,"y":685.0735294117648},{"id":1,"pressure":1,"x":312.94117647058823,"y":594.9264705882354}],"action":2},{"events":[{"id":0,"pressure":1,"x":407.05882352941177,"y":687.4264705882354},{"id":1,"pressure":1,"x":312.94117647058823,"y":592.5735294117648}],"action":2},{"events":[{"id":0,"pressure":1,"x":409.4117647058824,"y":689.7794117647059},{"id":1,"pressure":1,"x":310.5882352941177,"y":590.2205882352941}],"action":2},{"events":[{"id":0,"pressure":1,"x":411.7647058823529,"y":694.4852941176471},{"id":1,"pressure":1,"x":308.2352941176471,"y":585.5147058823529}],"action":2},{"events":[{"id":0,"pressure":1,"x":411.7647058823529,"y":699.1911764705883},{"id":1,"pressure":1,"x":308.2352941176471,"y":580.8088235294118}],"action":2},{"events":[{"id":0,"pressure":1,"x":414.11764705882354,"y":706.25},{"id":1,"pressure":1,"x":305.88235294117646,"y":573.75}],"action":2},{"events":[{"id":0,"pressure":1,"x":416.47058823529414,"y":713.3088235294118},{"id":1,"pressure":1,"x":303.5294117647059,"y":566.6911764705883}],"action":2},{"events":[{"id":0,"pressure":1,"x":418.8235294117647,"y":715.6617647058824},{"id":1,"pressure":1,"x":301.1764705882353,"y":564.3382352941177}],"action":2},{"events":[{"id":0,"pressure":1,"x":418.8235294117647,"y":718.0147058823529},{"id":1,"pressure":1,"x":301.1764705882353,"y":561.9852941176471}],"action":2},{"events":[{"id":0,"pressure":1,"x":418.8235294117647,"y":720.3676470588235},{"id":1,"pressure":1,"x":301.1764705882353,"y":559.6323529411765}],"action":2},{"events":[{"id":0,"pressure":1,"x":421.1764705882353,"y":727.4264705882354},{"id":1,"pressure":1,"x":298.8235294117647,"y":552.5735294117648}],"action":2},{"events":[{"id":0,"pressure":1,"x":421.1764705882353,"y":732.1323529411765},{"id":1,"pressure":1,"x":298.8235294117647,"y":547.8676470588235}],"action":2},{"events":[{"id":0,"pressure":1,"x":423.5294117647059,"y":739.1911764705883},{"id":1,"pressure":1,"x":296.47058823529414,"y":540.8088235294118}],"action":2},{"events":[{"id":0,"pressure":1,"x":425.88235294117646,"y":746.25},{"id":1,"pressure":1,"x":294.11764705882354,"y":533.75}],"action":2},{"events":[{"id":0,"pressure":1,"x":425.88235294117646,"y":753.3088235294118},{"id":1,"pressure":1,"x":294.11764705882354,"y":526.6911764705883}],"action":2},{"events":[{"id":0,"pressure":1,"x":428.2352941176471,"y":758.0147058823529},{"id":1,"pressure":1,"x":291.7647058823529,"y":521.9852941176471}],"action":2},{"events":[{"id":0,"pressure":1,"x":435.29411764705884,"y":765.0735294117648},{"id":1,"pressure":1,"x":284.70588235294116,"y":514.9264705882354}],"action":2},{"events":[{"id":0,"pressure":1,"x":440,"y":769.7794117647059},{"id":1,"pressure":1,"x":280,"y":510.22058823529414}],"action":2},{"events":[{"id":0,"pressure":1,"x":440,"y":779.1911764705883},{"id":1,"pressure":1,"x":280,"y":500.80882352941177}],"action":2},{"events":[{"id":0,"pressure":1,"x":444.7058823529412,"y":788.6029411764706},{"id":1,"pressure":1,"x":275.29411764705884,"y":491.39705882352945}],"action":2},{"events":[{"id":0,"pressure":1,"x":451.7647058823529,"y":800.3676470588235},{"id":1,"pressure":1,"x":268.2352941176471,"y":479.63235294117646}],"action":2},{"events":[{"id":0,"pressure":1,"x":456.47058823529414,"y":812.1323529411765},{"id":1,"pressure":1,"x":263.5294117647059,"y":467.86764705882354}],"action":2},{"events":[{"id":0,"pressure":1,"x":461.1764705882353,"y":821.5441176470589},{"id":1,"pressure":1,"x":258.8235294117647,"y":458.4558823529412}],"action":2},{"events":[{"id":0,"pressure":1,"x":465.88235294117646,"y":833.3088235294118},{"id":1,"pressure":1,"x":254.11764705882354,"y":446.69117647058823}],"action":2},{"events":[{"id":0,"pressure":1,"x":470.5882352941177,"y":840.3676470588235},{"id":1,"pressure":1,"x":249.41176470588235,"y":439.63235294117646}],"action":2},{"events":[{"id":0,"pressure":1,"x":475.29411764705884,"y":847.4264705882354},{"id":1,"pressure":1,"x":244.7058823529412,"y":432.5735294117647}],"action":2},{"events":[{"id":0,"pressure":1,"x":477.64705882352945,"y":854.4852941176471},{"id":1,"pressure":1,"x":242.3529411764706,"y":425.5147058823529}],"action":2},{"events":[{"id":0,"pressure":1,"x":482.3529411764706,"y":863.8970588235294},{"id":1,"pressure":1,"x":237.64705882352942,"y":416.1029411764706}],"action":2},{"events":[{"id":0,"pressure":1,"x":484.7058823529412,"y":870.9558823529412},{"id":1,"pressure":1,"x":235.29411764705884,"y":409.04411764705884}],"action":2},{"events":[{"id":0,"pressure":1,"x":489.4117647058824,"y":875.6617647058824},{"id":1,"pressure":1,"x":230.58823529411765,"y":404.3382352941177}],"action":2},{"events":[{"id":0,"pressure":1,"x":489.4117647058824,"y":878.0147058823529},{"id":1,"pressure":1,"x":230.58823529411765,"y":401.9852941176471}],"action":2},{"events":[{"id":0,"pressure":1,"x":491.764705882353,"y":882.7205882352941},{"id":1,"pressure":1,"x":228.23529411764707,"y":397.2794117647059}],"action":2},{"events":[{"id":0,"pressure":1,"x":494.11764705882354,"y":885.0735294117648},{"id":1,"pressure":1,"x":225.88235294117646,"y":394.9264705882353}],"action":2},{"events":[{"id":0,"pressure":1,"x":496.47058823529414,"y":892.1323529411765},{"id":1,"pressure":1,"x":223.52941176470588,"y":387.86764705882354}],"action":2},{"events":[{"id":0,"pressure":1,"x":501.1764705882353,"y":899.1911764705883},{"id":1,"pressure":1,"x":218.82352941176472,"y":380.80882352941177}],"action":2},{"events":[{"id":0,"pressure":1,"x":503.5294117647059,"y":908.6029411764706},{"id":1,"pressure":1,"x":216.47058823529412,"y":371.39705882352945}],"action":2},{"events":[{"id":0,"pressure":1,"x":505.88235294117646,"y":908.6029411764706},{"id":1,"pressure":1,"x":214.11764705882354,"y":371.39705882352945}],"action":2},{"events":[{"id":0,"pressure":1,"x":505.88235294117646,"y":910.9558823529412},{"id":1,"pressure":1,"x":214.11764705882354,"y":369.04411764705884}],"action":2},{"events":[{"id":0,"pressure":1,"x":505.88235294117646,"y":913.3088235294118},{"id":1,"pressure":1,"x":214.11764705882354,"y":366.69117647058823}],"action":2},{"events":[{"id":0,"pressure":1,"x":505.88235294117646,"y":913.3088235294118}],"action":1},{"events":[{"id":0,"pressure":1,"x":505.88235294117646,"y":913.3088235294118},{"id":1,"pressure":1,"x":214.11764705882354,"y":366.69117647058823}],"action":262}],"eventType":"MOTION"}
You can do it using adb getevent and sendevent. Connect you device using adb. Follow the steps below. Identify your Input device: Open any image on your device. To list input devices, run $ adb shell getevent add device 1: /dev/input/event7 name: "msm8226-tapan9302-snd-card Headset Jack" add device 2: /dev/input/event6 name: "msm8226-tapan9302-snd-card Button Jack" add device 3: /dev/input/event2 name: "synaptics_dsx_i2c" add device 4: /dev/input/event4 name: "qpnp_pon" Pinch in/out on the image, you should see some continuous logs like /dev/input/event2: 0003 0030 00000005 /dev/input/event2: 0000 0000 00000000 /dev/input/event2: 0003 002f 00000000 /dev/input/event2: 0003 0036 00000144 /dev/input/event2: 0003 003a 00000079 /dev/input/event2: 0000 0000 00000000 /dev/input/event2: 0003 0036 00000142 Confirms /dev/input/event2 is the input device name for my target device. Get exact getevent and convert getevent to sendevent: Make sure your screen switched on and is open with some image, Run the below command on the prompt. $ adb shell getevent | grep dev/input/event2 > getevent_input.txt While the above is running, Pinch in/out on the image on your phone. Once completed, Kill the above command Ctrl + C Open file getevent_input.txt and delete first line "add device X: /dev/input/eventX" from it. Since getevent returns values in decimal, and sendevent takes value in hexadecimal. We have to do the above conversion. This script hex_to_dec.py here does the Job. Thanks to this guy! $./hex_to_dec.py getevent_input.txt Generates a file getevent_input.scr, Now rename this file to .sh $ mv getevent_input.scr sendevent_input.sh Open file sendevent_input.sh and delete second line "echoing – drawing function" and save it. Run on device. Transfer sendevent_input.sh to device. $ adb push sendevent_input.sh /sdcard/ 1615 KB/s (64379 bytes in 0.038s) Make sure you device has an image open, and screen is not off. $ adb shell sh /sdcard/sendevent_input.sh Worked perfectly fine for me, If this what you looking for. For visible results, enable Show touches in Developer Options. Environment: Motorola Moto G (Android 4.4.4) with ADB (v 1.0.31) on Ubuntu 12.04.
A (kind of hacky) solution with adb shell input looks like adb shell input tap 200 200 & PIDTAP=$! sleep 0.1 adb shell input swipe 200 200 200 100 1000 & PIDSWIPE=$! wait $PIDTAP wait $PIDSWIPE The idea is that we launch TAP command, then short sleep and then perform SWIPE. Such commands sequence is interpreted as tap + swipe hence zoom is performed. The example above would be a zoom out on a map.
Interpretation of the result of "cat /proc/bus/input/devices" and adb shell commands
I'm unsure if the question about injecting events via adb is supposed to be in StackOverflow or Android Enthusiasts, please move it if it doesn't belong here. Anyway, my question is as follows. I obviously have to determine the "type" of device for sending and receiving events. I can't obviously send a touch event to the keypad device. After a lot of research I found the sendevent and getevent commands. So, I want to send a long press to the power button of a phone. I use this currently: sendevent /dev/input/event3 1 116 0 sendevent /dev/input/event3 1 116 1 This works on the HTC Wildfire(click on the link for the input devices) because the keypad contains the power button and 116 happens to be the scan code for the power key. I know what /dev/input/event3/ and 116 and 0 or 1 stand for. What does the 1 in-between /dev/input/event3/ and 116 stand for? How do I obtain it? Moving on to the Nexus 4. Now, I've noticed that it has a separate powerkey and keypad handler [EDIT] Found this regarding sendevent and getevent on XDA.
The 1 "in-between /dev/input/event3/ and 116" stands for EV_KEY event type constant: EV_KEY: Used to describe state changes of keyboards, buttons, or other key-like devices. You could have found that on your own if you had run getevent -l /dev/input/event3/ and pressed the power key. Also to find out the power key input device name I would recommend parsing output of getevent -pl instead of contents of /proc/bus/input/devices. The device you are looking for has KEY_POWER listed in the events section: add device X: /dev/input/eventX name: "xxxxxxxxxx" events: KEY (0001): KEY_POWER And the proper long power key press sequence (as in press and hold for 1 second and then release) would be: sendevent /dev/input/eventX 1 116 1 sendevent /dev/input/eventX 0 0 0 sleep 1 sendevent /dev/input/eventX 1 116 0 sendevent /dev/input/eventX 0 0 0 Note: getevent -pl is not available for Gingerbread and below.
How can I use adb to send a longpress key event?
I can use something like: adb shell input keyevent 4 and this will send a single 'Back' button press to my device. How can I send a longpress? Thanks
You can try this command: adb shell input touchscreen swipe 170 187 170 187 2000 Your application position on screen is 170, 187; delay time is 2000 (ms); Long press HOME key: adb shell sendevent /dev/input/event2 1 172 1 adb shell sendevent /dev/input/event2 0 0 0 timeout 1 adb shell sendevent /dev/input/event2 1 172 0 adb shell sendevent /dev/input/event2 0 0 0 You can goto cmd and type adb shell getevent | find "event2" ; long press HOME key to see more.
Since this commit in Android 4.4 it is possibile to use: adb shell input keyevent --longpress KEYCODE_L This other commit further improved the behaviour.
When you want to delete something or repeat some Event or just input a lot of numbers, you can use code like the following. It will imitate a longpress on a keyboard: adb shell input keyevent KEYCODE_FORWARD_DEL KEYCODE_FORWARD_DEL KEYCODE_FORWARD_DEL //delete 3 times adb shell input keyevent KEYCODE_1 KEYCODE_1 KEYCODE_1 //input value '111' You can repeat the event or input things without limits, just like a Longpress on the key. It's the same thing. You can define your own longpass and times Now
This link discusses a similar problem, but the device in question (a Nexus One device)has the menu/home/back/search buttons as part of the touchscreen, not physical keys. This other one appears to be more inline with injecting a physical key input, but requires accessing the *.kl file for your devices driver to determine the device, type, key-code, value-press, and value-release codes for that specific device. However, the common link between the two appears to be adb shell sleep n , where n is the length (in seconds) of the press duration. Hopefully this might be of some use.
Well, this developer link show the keycode is 128, which i already test, but no expected result You can check this link and this link. They show how to find it.
This might be too late to answer but surely will help others. Please use below cmd to achieve long press. adb shell input keyevent 5 sleep 5
How to use ADB to send touch events to device using sendevent command?
I am trying to send touch events to a device using AndroidDebugBridge, so that I can do some basic automation for UI tests. I have followed the discussion in LINK. I am able to use sendevent to simulate touch on emulators, but unable to do the same on a device. Like in above link the emulator seems to send out 6 events for each touch ( xcoord, ycoord, 2 for press,2 for release) and it was easy to use this information to sendevents, but a getevent for the touchscreen for a device seems to generate far too many events. Has somebody managed to send touch from ADB to a device? Could you please share the solution.
Android comes with an input command-line tool that can simulate miscellaneous input events. To simulate tapping, it's: input tap x y You can use the adb shell ( > 2.3.5) to run the command remotely: adb shell input tap x y
In order to do a particular action (for example to open the web browser), you need to first figure out where to tap. To do that, you can first run: adb shell getevent -l Once you press on the device, at the location that you want, you will see this output: <...> /dev/input/event3: EV_KEY BTN_TOUCH DOWN /dev/input/event3: EV_ABS ABS_MT_POSITION_X 000002f5 /dev/input/event3: EV_ABS ABS_MT_POSITION_Y 0000069e adb is telling you that a key was pressed (button down) at position 2f5, 69e in hex which is 757 and 1694 in decimal. If you now want to generate the same event, you can use the input tap command at the same position: adb shell input tap 757 1694 More info can be found at: https://source.android.com/devices/input/touch-devices.html http://source.android.com/devices/input/getevent.html
2.3.5 did not have input tap, just input keyevent and input text You can use the monkeyrunner for it: (this is a copy of the answer at https://stackoverflow.com/a/18959385/1587329): You might want to use monkeyrunner like this: $ monkeyrunner >>> from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice >>> device = MonkeyRunner.waitForConnection() >>> device.touch(200, 400, MonkeyDevice.DOWN_AND_UP) You can also do a drag, start activies etc. Have a look at the api for MonkeyDevice.
You don't need to use adb shell getevent -l command, you just need to enable in Developer Options on the device [Show Touch data] to get X and Y. Some more information can be found in my article here: https://mobileqablog.wordpress.com/2016/08/20/android-automatic-touchscreen-taps-adb-shell-input-touchscreen-tap/
Building on top of Tomas's answer, this is the best approach of finding the location tap position as an integer I found: adb shell getevent -l | grep ABS_MT_POSITION --line-buffered | awk '{a = substr($0,54,8); sub(/^0+/, "", a); b = sprintf("0x%s",a); printf("%d\n",strtonum(b))}' Use adb shell getevent -l to get a list of events, the using grep for ABS_MT_POSITION (gets the line with touch events in hex) and finally use awk to get the relevant hex values, strip them of zeros and convert hex to integer. This continuously prints the x and y coordinates in the terminal only when you press on the device. You can then use this adb shell command to send the command: adb shell input tap x y
Consider using Android's uiautomator, with adb shell uiautomator [...] or directly using the .jar that comes with the SDK.