Need Emulator SD Card writable permission for screenshot code

Hi,

I am running UI tests on an android API 19 and have been struggling to figure out why the screenshot code fails on bitrise but works locally. After much searching, I have a strong lead but need some help finishing this out.

I use square’s Spoon to run my tests, which has built in screenshot code, althought it does not capture proper screenshots for custom views, so i delegate the screenshot part to UiDevices’s takeScreenshot:

Context c = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
            File file = new File(c.getExternalCacheDir(), tag + ".png");
            UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).takeScreenshot(file);
            Spoon.save(c, file);

This works great locally, but i get an exception when run on bitrise:
“Can’t find any file at: /storage/sdcard/Android/data/com.my.package/cache/screenshot.png”

On another forum i read that CI emulators require the SD card to be created via the avd options in order to get write permissions, so here is the avd creation command with SD card settings: (https://github.com/square/spoon/issues/283)

mksdcard -l e 512M mysdcard.img

emulator_name=android-19
echo no | android create avd --force -n $emulator_name -t android-19 --abi armeabi-v7a --sdcard mysdcard.img

and for booting the emaultor i added SD to this command as well:

-no-boot-anim -no-audio -no-window -sdcard mysdcard.img

I check the SD card permission, looks like its got read and write

adb shell ls -l /storage/
drwxrwx--x root     sdcard_r          2017-02-01 23:09 sdcard

And yes, both the app apk and test apk have the android.permission.WRITE_EXTERNAL_STORAGE and android.permission.READ_EXTERNAL_STORAGE permissions.

Any help much appreciated! Am i setting the SD card correctly?

1 Like

Does it work if you do this on your Mac/PC, with the same scripts/parameters?

Another thing worth to try is to download the bitrise.io Android build environment with Docker: http://devcenter.bitrise.io/docker/run-your-build-locally-in-docker/
You’ll most likely get the same error there (after all this is the same environment), but this might help you with debugging, as you can “jump into” the environment and try different things quickly, instead of waiting for the result of a build.

Is this the exact error message? Can you please include a bit more of the log, around the error?

That is the exact error message that i catch:
try{
if(screenshots_enabled){
numScreenshots++;
Context c = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
final File file = new File(c.getExternalCacheDir(), “” + numScreenshots + “_” + tag + “.png”);
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).takeScreenshot(file);
Spoon.save(c, file);
}
}
catch(Exception e){
Log.w(TAG, "SPOON SCREENSHOT WAS NOT ABLE TO BE CAPTURED!!! MESSAGE = "
+ e.getMessage() +
"TO STRING = " + e.toString() +
}

i run the spoon command using fastlane locally, which runs the test on any booted emulators - i use genymotion mostly, and it worked on API 19 . in bitrise i run the same fastlane command but the emulator is different since its created using avd command. locally i dont have the same android targets atm. i will give the bitrise docker a try!

Please do (or use the Bitrise CLI or Terminal to create the emulator and test with that), and let us know how it goes / if you can figure this out, or if you have any questions!