Tuesday, February 28, 2017

WildMidi for Android: Compiling WildMidi using Android NDK rev 13

Android had no standard midi protocol before Marshmallow. Even after a standard MIDI event API for a developer to build android app which does midi synthesis by itself is a great feature!. In 2016 i compiled FluidSynth 1.6 for Android and created a SoundFont Midi Player with USB keyboard support. This app can play midi, rmi files and can send midi events via USB MIDI Keyboard, Normal USB keyboard to fluidsynth to synthesize sound. Due to latency and high CPU consumption issues i decided to look at other options. One good option was WildMidi.

WildMidi - https://www.mindwerks.net/projects/wildmidi/

It says -

"The WildMIDI library uses Gravis Ultrasound patch files to convert MIDI files into audio which is then passed back to the calling application for further processing or output

Library Features

  • RIFF MIDI file support
  • MIDI format 0, 1 and 2 support
  • MIDI-like formats: KAR, HMI, HMP, MUS and XMI
  • Cross Platform: Linux, Windows, OSX, FreeBSD and etc.
  • Thread safe
  • host-Endian native streaming
  • WAV file output
  • Linear and gauss re-sampling
  • Final output reverb engine
  • Timidity.cfg compatibility
Player Features

  • OSS and Alsa Output (Linux/FreeBSD)
  • Windows Sound System support (Windows)
  • OpenAL (OSX/Others)
  • SoundBlaster 16 (DOS)"

In Player features Android sound system is not mentioned and that doesn't mean it cannot be used in Android. I compiled WildMidi for Android and the link to download the binary package is mentioned later in this page. I tested WildMidi on Ubuntu-Studio which had inbuilt "FreePats". The Gravis Ultrasound Patch files are used by WildMidi to synthesize sound. We can use WildMidi player to play midi files on Android by modifying its player code by sending PCM buffer to Android OpenSLES or AudioTrack.

Can wildmidi be used for sending MIDI events to build piano like app with fast response? Currently NO as per wildmidi source!

Looking at source code of wildmidi inside wildmidi_lib.h. It says "Not Yet Implemented". That "latency" thing! everywhere.

/* NOTE: Not Yet Implemented Or Tested Properly */
/* Due to delay in audio output in the player, this is not being developed
   futher at the moment. Further Development will occur when output latency
   has been reduced enough to "appear" instant.
WM_SYMBOL int WildMidi_Live (midi * handle, uint32_t midi_event);

/* reserved for future coding
 * need to change these to use a time for cmd_pos and new_cmd_pos

WM_SYMBOL int WildMidi_InsertMidiEvent (midi * handle, uint8_t char midi_cmd, *char midi_cmd_data, unsigned long int midi_cmd_data_size, unsigned long int *cmd_pos);
WM_SYMBOL int WildMidi_DeleteMidiEvent (midi * handle, uint8_t char midi_cmd, unsigned long int *cmd_pos);
WM_SYMBOL int WildMidi_MoveMidiEvent (midi * handle, , uint8_t char midi_cmd, unsigned long int *cmd_pos, unsigned long int *new_cmd_pos);

This can be used to build a midi player for android using wildmidi synthesizer. The build script is same as libpng build script mentioned on my other article.

Download wildmidi arm binary from here:

Saturday, February 25, 2017

NEW: Building libpng 1.6.28 using Android NDK r13 CMake based build system

I recently updated to NDK revision 13 and also found ndk samples are now cmake + ninja based. Today 3-4 hours were consumed while trying to compile libpng but finally done it after editing CMakeLists.txt of libpng.

I tried to build libpng using Androud Studio's Gradle plugin from IDE but that was more problematic as it too required CMakeLists.txt editing and kept throwing bad link to libpng.so error. I decided to use shell which is my 1st and last choice to work in most cases. Before putting the scripts/code lets setup our work directory and data and also look at how cmake based build system compiles libpng.

Before starting ensure below tools are installed and working correctly on your system.

  • Android NDK revision 12+ is installed. If you have Android SDK installed but NDK is at some other location then you can move NDK inside SDK and rename it to ndk-bundle Or create a sym-link "ndk-bundle" in SDK pointing to actual NDK. After this NDK will start showing in the Android Studio 2.2+ SDK manager.
  • Install cmake from SDK manager. It will get extracted in Android SDK directory.
  • A good command shell. I use Ubuntu-Studio Linux with bash shell(s). Windows users can use cmd.exe or bash shell through UnixUtils.

Build process:

  1. Dowload libpng 1.6.28 from here http://ftp.osuosl.org/pub/blfs/conglomeration/libpng/libpng-1.6.28.tar.xz and extract to some location with shorter path without spaces. e.g. /home/username/projects/libpng in Linux or c:\work\libpng in windows. This is for convenience and avoid space related issues while compiling.
  2. Copy full path of android.toolchain.cmake present in NDK. Example /media/bindesh/WORK/SDK_IDE/android-ndk-r13b/build/cmake/android.toolchain.cmake. There is same named file present in ANDROID_SDK/cmake/ like this /media/bindesh/WORK/SDK_IDE/android-sdk-linux-windows/cmake/3.6.3155560/android.toolchain.cmake but we must use toolchain file present in NDK. If toolchain present in sdk/cmake is used incompatibility issues like "Invalid Android NDK revision (should be 12" can occur.
  3. Open libpng/CMakeLists.txt file in text editor and add include("/home/bindesh/bin/ndk/build/cmake/android.toolchain.cmake") line after project(libpng C). Change the NDK path to yours.

Copy below bash script to create a file build.sh in libpng folder. Change the cmake, ninja, toolchain, sdk, ndk paths in script and run to build libpng. Replace the toolchain path copied through above steps. I have not tested this on Windows but using UnixUtils's sh.exe it should work.

build script:

# run this script after changing the paths of ndk, sdk, cmake, ninja etc to build libpng or other cmake based library.
# Don't forget to add below line in main CMakeLists.txt after project() line of code.
# include("PATH_TO_NDK/build/cmake/android.toolchain.cmake")


# clean previous files
rm CMakeCache.txt

# Change these paths and run this script to build libpng


# Don't use toolchain from cmake




mv ./libpng16.a ./libpng16-${ANDROID_ABI}.a


Below is the CMakeOutput.log to check details of build environment.

The target system is: Android - 9 - armv7-a
The host system is: Linux - 4.8.0-22-lowlatency - x86_64
Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded.
Compiler: /home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc 
Build flags: -g;-DANDROID;-ffunction-sections;-funwind-tables;-fstack-protector-strong;-no-canonical-prefixes;-march=armv7-a;-mfloat-abi=softfp;-mfpu=vfpv3-d16;-mthumb;-Wa,--noexecstack;-Wformat;-Werror=format-security;-g;-DANDROID;-ffunction-sections;-funwind-tables;-fstack-protector-strong;-no-canonical-prefixes;-march=armv7-a;-mfloat-abi=softfp;-mfpu=vfpv3-d16;-mthumb;-Wa,--noexecstack;-Wformat;-Werror=format-security;
Id flags: -c

The output was:

Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "CMakeCCompilerId.o"

The C compiler identification is GNU, found in "/media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/3.6.0-rc2/CompilerIdC/CMakeCCompilerId.o"

Determining if the C compiler works passed with the following output:
Change Dir: /media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/CMakeTmp

Run Build Command:"/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_76f0a"
[1/2] Building C object CMakeFiles/cmTC_76f0a.dir/testCCompiler.c.o
[2/2] Linking C executable cmTC_76f0a

Detecting C compiler ABI info compiled with the following output:
Change Dir: /media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/CMakeTmp

Run Build Command:"/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_7ad81"
[1/2] Building C object CMakeFiles/cmTC_7ad81.dir/CMakeCCompilerABI.c.o
[2/2] Linking C executable cmTC_7ad81
Using built-in specs.
Target: arm-linux-androideabi
Configured with: /usr/local/google/buildbot/src/android/gcc/toolchain/build/../gcc/gcc-4.9/configure --prefix=/tmp/59719db9ae19ff43aef46bbcb79596b6 --target=arm-linux-androideabi --host=x86_64-linux-gnu --build=x86_64-linux-gnu --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --with-gmp=/buildbot/tmp/build/toolchain/temp-install --with-mpfr=/buildbot/tmp/build/toolchain/temp-install --with-mpc=/buildbot/tmp/build/toolchain/temp-install --with-cloog=/buildbot/tmp/build/toolchain/temp-install --with-isl=/buildbot/tmp/build/toolchain/temp-install --with-ppl=/buildbot/tmp/build/toolchain/temp-install --disable-ppl-version-check --disable-cloog-version-check --disable-isl-version-check --enable-cloog-backend=isl --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --disable-libssp --enable-threads --disable-nls --disable-libmudflap --disable-libgomp --disable-libstdc__-v3 --disable-sjlj-exceptions --disable-shared --disable-tls --disable-libitm --with-float=soft --with-fpu=vfp --with-arch=armv5te --enable-target-optspace --enable-bionic-libs --enable-libatomic-ifuncs=no --enable-initfini-array --disable-nls --prefix=/tmp/59719db9ae19ff43aef46bbcb79596b6 --with-sysroot=/tmp/59719db9ae19ff43aef46bbcb79596b6/sysroot --with-binutils-version=2.25 --with-mpfr-version=3.1.1 --with-mpc-version=1.0.1 --with-gmp-version=5.0.5 --with-gcc-version=4.9 --with-gdb-version=none --with-gxx-include-dir=/tmp/59719db9ae19ff43aef46bbcb79596b6/include/c++/4.9.x --with-bugurl=http://source.android.com/source/report-bugs.html --enable-languages=c,c++ --disable-bootstrap --enable-plugins --enable-libgomp --enable-gnu-indirect-function --disable-libsanitizer --enable-gold --enable-threads --enable-eh-frame-hdr-for-static --enable-graphite=yes --with-isl-version=0.11.1 --with-cloog-version=0.18.0 --with-arch=armv5te --program-transform-name='s&^&arm-linux-androideabi-&' --enable-gold=default
Thread model: posix
gcc version 4.9.x 20150123 (prerelease) (GCC) 
COLLECT_GCC_OPTIONS='-g' '-D' 'ANDROID' '-fstack-protector-strong' '-march=armv7-a' '-mfloat-abi=softfp' '-mfpu=vfpv3-d16' '-mthumb' '-Wformat=1' '-Werror=format-security' '-g' '-D' 'ANDROID' '-ffunction-sections' '-funwind-tables' '-fstack-protector-strong' '-march=armv7-a' '-mfloat-abi=softfp' '-mfpu=vfpv3-d16' '-mthumb' '-Wformat=1' '-Werror=format-security' '-v' '-o' 'cmTC_7ad81' '-mtls-dialect=gnu'
 /home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/collect2 -plugin /home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/liblto_plugin.so -plugin-opt=/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/lto-wrapper -plugin-opt=-fresolution=/tmp/ccNet1nu.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-ldl -plugin-opt=-pass-through=-lgcc --sysroot=/home/bindesh/bin/ndk/platforms/android-9/arch-arm --eh-frame-hdr -dynamic-linker /system/bin/linker -X -m armelf_linux_eabi -z noexecstack -z relro -z now -o cmTC_7ad81 /home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib/crtbegin_dynamic.o -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a/thumb -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib -L/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib --build-id --warn-shared-textrel --fatal-warnings --fix-cortex-a8 --no-undefined -z noexecstack -z relro -z now --gc-sections -z nocopyreloc CMakeFiles/cmTC_7ad81.dir/CMakeCCompilerABI.c.o -lgcc -lc -ldl -lgcc /home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib/crtend_android.o

Parsed C implicit link information from above output:
  link line regex: [^( *|.*[/\])(arm-linux-androideabi-ld|([^/\]+-)?ld|collect2)[^/\]*( |$)]
  ignore line: [Change Dir: /media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/CMakeTmp]
  ignore line: []
  ignore line: [Run Build Command:"/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_7ad81"]
  ignore line: [[1/2] Building C object CMakeFiles/cmTC_7ad81.dir/CMakeCCompilerABI.c.o]
  ignore line: [[2/2] Linking C executable cmTC_7ad81]
  ignore line: [Using built-in specs.]
  ignore line: [COLLECT_GCC=/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc]
  ignore line: [COLLECT_LTO_WRAPPER=/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/lto-wrapper]
  ignore line: [Target: arm-linux-androideabi]
  ignore line: [Configured with: /usr/local/google/buildbot/src/android/gcc/toolchain/build/../gcc/gcc-4.9/configure --prefix=/tmp/59719db9ae19ff43aef46bbcb79596b6 --target=arm-linux-androideabi --host=x86_64-linux-gnu --build=x86_64-linux-gnu --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --with-gmp=/buildbot/tmp/build/toolchain/temp-install --with-mpfr=/buildbot/tmp/build/toolchain/temp-install --with-mpc=/buildbot/tmp/build/toolchain/temp-install --with-cloog=/buildbot/tmp/build/toolchain/temp-install --with-isl=/buildbot/tmp/build/toolchain/temp-install --with-ppl=/buildbot/tmp/build/toolchain/temp-install --disable-ppl-version-check --disable-cloog-version-check --disable-isl-version-check --enable-cloog-backend=isl --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --disable-libssp --enable-threads --disable-nls --disable-libmudflap --disable-libgomp --disable-libstdc__-v3 --disable-sjlj-exceptions --disable-shared --disable-tls --disable-libitm --with-float=soft --with-fpu=vfp --with-arch=armv5te --enable-target-optspace --enable-bionic-libs --enable-libatomic-ifuncs=no --enable-initfini-array --disable-nls --prefix=/tmp/59719db9ae19ff43aef46bbcb79596b6 --with-sysroot=/tmp/59719db9ae19ff43aef46bbcb79596b6/sysroot --with-binutils-version=2.25 --with-mpfr-version=3.1.1 --with-mpc-version=1.0.1 --with-gmp-version=5.0.5 --with-gcc-version=4.9 --with-gdb-version=none --with-gxx-include-dir=/tmp/59719db9ae19ff43aef46bbcb79596b6/include/c++/4.9.x --with-bugurl=http://source.android.com/source/report-bugs.html --enable-languages=c,c++ --disable-bootstrap --enable-plugins --enable-libgomp --enable-gnu-indirect-function --disable-libsanitizer --enable-gold --enable-threads --enable-eh-frame-hdr-for-static --enable-graphite=yes --with-isl-version=0.11.1 --with-cloog-version=0.18.0 --with-arch=armv5te --program-transform-name='s&^&arm-linux-androideabi-&' --enable-gold=default]
  ignore line: [Thread model: posix]
  ignore line: [gcc version 4.9.x 20150123 (prerelease) (GCC) ]
  ignore line: [COMPILER_PATH=/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/:/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/:/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/]
  ignore line: [LIBRARY_PATH=/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb/:/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a/thumb/:/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/:/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/:/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/:/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib/]
  ignore line: [COLLECT_GCC_OPTIONS='-g' '-D' 'ANDROID' '-fstack-protector-strong' '-march=armv7-a' '-mfloat-abi=softfp' '-mfpu=vfpv3-d16' '-mthumb' '-Wformat=1' '-Werror=format-security' '-g' '-D' 'ANDROID' '-ffunction-sections' '-funwind-tables' '-fstack-protector-strong' '-march=armv7-a' '-mfloat-abi=softfp' '-mfpu=vfpv3-d16' '-mthumb' '-Wformat=1' '-Werror=format-security' '-v' '-o' 'cmTC_7ad81' '-mtls-dialect=gnu']
  link line: [ /home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/collect2 -plugin /home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/liblto_plugin.so -plugin-opt=/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/lto-wrapper -plugin-opt=-fresolution=/tmp/ccNet1nu.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-ldl -plugin-opt=-pass-through=-lgcc --sysroot=/home/bindesh/bin/ndk/platforms/android-9/arch-arm --eh-frame-hdr -dynamic-linker /system/bin/linker -X -m armelf_linux_eabi -z noexecstack -z relro -z now -o cmTC_7ad81 /home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib/crtbegin_dynamic.o -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a/thumb -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc -L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib -L/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib --build-id --warn-shared-textrel --fatal-warnings --fix-cortex-a8 --no-undefined -z noexecstack -z relro -z now --gc-sections -z nocopyreloc CMakeFiles/cmTC_7ad81.dir/CMakeCCompilerABI.c.o -lgcc -lc -ldl -lgcc /home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib/crtend_android.o]
    arg [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/collect2] ==> ignore
    arg [-plugin] ==> ignore
    arg [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/liblto_plugin.so] ==> ignore
    arg [-plugin-opt=/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/lto-wrapper] ==> ignore
    arg [-plugin-opt=-fresolution=/tmp/ccNet1nu.res] ==> ignore
    arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
    arg [-plugin-opt=-pass-through=-lc] ==> ignore
    arg [-plugin-opt=-pass-through=-ldl] ==> ignore
    arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
    arg [--sysroot=/home/bindesh/bin/ndk/platforms/android-9/arch-arm] ==> ignore
    arg [--eh-frame-hdr] ==> ignore
    arg [-dynamic-linker] ==> ignore
    arg [/system/bin/linker] ==> ignore
    arg [-X] ==> ignore
    arg [-m] ==> ignore
    arg [armelf_linux_eabi] ==> ignore
    arg [-znoexecstack] ==> ignore
    arg [-zrelro] ==> ignore
    arg [-znow] ==> ignore
    arg [-o] ==> ignore
    arg [cmTC_7ad81] ==> ignore
    arg [/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib/crtbegin_dynamic.o] ==> ignore
    arg [-L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb] ==> dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb]
    arg [-L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a/thumb] ==> dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a/thumb]
    arg [-L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x] ==> dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x]
    arg [-L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc] ==> dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc]
    arg [-L/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib] ==> dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib]
    arg [-L/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib] ==> dir [/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib]
    arg [--build-id] ==> ignore
    arg [--warn-shared-textrel] ==> ignore
    arg [--fatal-warnings] ==> ignore
    arg [--fix-cortex-a8] ==> ignore
    arg [--no-undefined] ==> ignore
    arg [-znoexecstack] ==> ignore
    arg [-zrelro] ==> ignore
    arg [-znow] ==> ignore
    arg [--gc-sections] ==> ignore
    arg [-znocopyreloc] ==> ignore
    arg [CMakeFiles/cmTC_7ad81.dir/CMakeCCompilerABI.c.o] ==> ignore
    arg [-lgcc] ==> lib [gcc]
    arg [-lc] ==> lib [c]
    arg [-ldl] ==> lib [dl]
    arg [-lgcc] ==> lib [gcc]
    arg [/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib/crtend_android.o] ==> ignore
  remove lib [gcc]
  remove lib [gcc]
  collapse library dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb] ==> [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb]
  collapse library dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a/thumb] ==> [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/lib/armv7-a/thumb]
  collapse library dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x] ==> [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x]
  collapse library dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc] ==> [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc]
  collapse library dir [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib] ==> [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/lib]
  collapse library dir [/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib] ==> [/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib]
  implicit libs: [c;dl]
  implicit dirs: [/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/thumb;/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/lib/armv7-a/thumb;/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x;/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc;/home/bindesh/bin/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/lib;/home/bindesh/bin/ndk/platforms/android-9/arch-arm/usr/lib]
  implicit fwks: []

Detecting C [-std=c11] compiler features compiled with the following output:
Change Dir: /media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/CMakeTmp

Run Build Command:"/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_5d10b"
[1/2] Building C object CMakeFiles/cmTC_5d10b.dir/feature_tests.c.o
[2/2] Linking C executable cmTC_5d10b

    Feature record: C_FEATURE:1c_function_prototypes
    Feature record: C_FEATURE:1c_restrict
    Feature record: C_FEATURE:1c_static_assert
    Feature record: C_FEATURE:1c_variadic_macros

Detecting C [-std=c99] compiler features compiled with the following output:
Change Dir: /media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/CMakeTmp

Run Build Command:"/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_bb98c"
[1/2] Building C object CMakeFiles/cmTC_bb98c.dir/feature_tests.c.o
[2/2] Linking C executable cmTC_bb98c

    Feature record: C_FEATURE:1c_function_prototypes
    Feature record: C_FEATURE:1c_restrict
    Feature record: C_FEATURE:0c_static_assert
    Feature record: C_FEATURE:1c_variadic_macros

Detecting C [-std=c90] compiler features compiled with the following output:
Change Dir: /media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/CMakeTmp

Run Build Command:"/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_f387f"
[1/2] Building C object CMakeFiles/cmTC_f387f.dir/feature_tests.c.o
[2/2] Linking C executable cmTC_f387f

    Feature record: C_FEATURE:1c_function_prototypes
    Feature record: C_FEATURE:0c_restrict
    Feature record: C_FEATURE:0c_static_assert
    Feature record: C_FEATURE:0c_variadic_macros
Performing C SOURCE FILE Test HAVE_LD_VERSION_SCRIPT succeeded with the following output:
Change Dir: /media/bindesh/WORK/00_write/libpng-1.6.28/CMakeFiles/CMakeTmp

Run Build Command:"/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_d0d1b"
[1/2] Building C object CMakeFiles/cmTC_d0d1b.dir/src.c.o
[2/2] Linking C executable cmTC_d0d1b

Source file was:
void sym(void) {}
void sym2(void) {}
int main(void) {return 0;}

Head of CMakeLists.txt file for reference

# CMakeLists.txt

# Copyright (C) 2007,2009-2016 Glenn Randers-Pehrson
# Written by Christian Ehrlicher, 2007
# Revised by Roger Lowman, 2009-2010
# Revised by Clifford Yapp, 2011-2012
# Revised by Roger Leigh, 2016
# Revised by Andreas Franek, 2016

# This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer
# and license in png.h

cmake_minimum_required(VERSION 2.8.3)
cmake_policy(VERSION 2.8.3)

# Set MacOSX @rpath usage globally.
if (POLICY CMP0020)
  cmake_policy(SET CMP0020 NEW)
endif(POLICY CMP0020)
if (POLICY CMP0042)
  cmake_policy(SET CMP0042 NEW)
endif(POLICY CMP0042)
# Use new variable expansion policy.
if (POLICY CMP0053)
  cmake_policy(SET CMP0053 NEW)
endif(POLICY CMP0053)
if (POLICY CMP0054)
  cmake_policy(SET CMP0054 NEW)
endif(POLICY CMP0054)

set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")

project(libpng C)



# needed packages

#Allow users to specify location of Zlib, 
# Useful if zlib is being built alongside this as a sub-project
option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" OFF) 

This script will build libpng for specified ABI. Change the ABI to build x86, MIPS etc binaries. Sample output binary for above script can be downloaded from here:


Wednesday, February 22, 2017

Android Studio NDK and CMake build system. Compiling hello-jni using cmake without Android Studio.

This post will be short and to the point. Android Studio and development tools have reached very stable and feature rich state in past few years after Android Studio was released. However it is still hard for many developers trying to use NDK 1st time. Now NDK has become more easier than before!. Thanks to CMake build system.

While building many c/c++ libraries like libpng, webp, fluidsynth, imagemagick, jpegoptim, vorbis, freetype etc i used Android.mk based build system. However while looking at new ndk samples i found CMake based source codes. Lets start learning basics of CMake build system by building hello-jni without using Android Studio.

Firstly ensure all SDK and NDK are installed before proceeding further. Use SDK manager to install platform, platform-tools, build-tools, tools (SDK tools), cmake, ndk and other required packages like Google support libraries. After all is done the directories in the installed location will contain these folders -

... etc

In list above we can see cmake version. This means cmake is installed. Before cmake ndk-build command was used to build c/c++ codes present inside jni folder. That ndk-build script required some hard-coded paths like presence of jni folder, manifest file. Using Cmake its more convenient to build native binaries.

Download hello-jni from here. Extract the zip go to hello-jni/app/src/main/cpp/ and start a command shell bash etc in Linux and cmd.exe etc in Windows. Execute cmake from shell. Like this -

/home/bindesh/bin/android-sdk/cmake/3.6.3155560/bin/cmake -DCMAKE_TOOLCHAIN_FILE=/home/bindesh/bin/ndk/build/cmake/android.toolchain.cmake

This command tells cmake to use Android NDK's toolchain to build ARM/X86/MIPS binary. It dumps text like below -

-- Check for working C compiler: /home/bindesh/bin/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang
-- Check for working C compiler: /home/bindesh/bin/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /home/bindesh/bin/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
-- Check for working CXX compiler: /home/bindesh/bin/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /media/bindesh/WORK/Software/Android/NDK/android-ndk-master/hello-jni/app/src/main/cpp

CMake's job is to identify development tools and configuration. The job of toolchain file it to supply the configuration. Open android.toolchain.cmake file in a text editor to see what it does. CMake creates a Makefile by default. After Makefile is created run make and this will show messages like -

[ 50%] Building C object CMakeFiles/hello-jni.dir/hello-jni.c.o
[100%] Linking C shared library libhello-jni.so
[100%] Built target hello-jni

libhello-jni.so file is created and ready to be used by Android Java project. Cmake can be used to easily change project configurations like adding libraries, custom header paths, external libraries etc.

You can read about cmake in Android NDK docs here https://developer.android.com/ndk/guides/cmake.html#build-command

To learn more how jni binary was built you can read contents of CMakeFiles folder created by cmake. In this folder more details can be found. For example hello-jni/app/src/main/cpp/CMakeFiles/hello-jni.dir/flags.make file contains the CFLAGS, -D, -I, -L flags we pass in a makefile or Android.mk. The good thing is we have to deal with CMakeLists.txt file ONLY. All thing is done from here. Refer to cmake help pages for more information. Use cmake --help to see what more it can do. This article focused on building hello-jni from command like without using Android Studio.

Important links -





This article is very short so i will probably (if i didn't forgot!) write advanced ndk project compilation articles like compiling libpng, libjpeg etc using CMake.

Tuesday, February 7, 2017

Useful Collection of Public Domain, Creative Commons, Free sounds and graphics for commercial use

As an Indie developer i required lot of free sound, music and game art for commercial use. Internet is huge but it still lacks resources with permissible license. Looking for free stuff is not bad but also not great because every work has value and in real life there is no free meal. There are very helping people who offer their work for free to ease development work of indie workers. Below are links to such useful assets.



A website with lots of free multimedia resources. Contains 2D, 3D, music, sound etc stuff with search and page wise browsing. It includes resources with multiple types of open licenses.

Kenney Vleugels website:


"We've created over 35,000 images, audio files and 3D models for you to use in your projects. Thanks to our public domain license you're even allowed to use them in commercial projects!"

220+MB of arts and sounds.

Glitch Game Art


"The collaborative, web-based, massively multiplayer game Glitch began its initial private testing in 2009, opened to the public in 2010, and was shut down in 2012. It was played by more than 150,000 people and was widely hailed for its original and highly creative visual style.

The entire library of art assets from the game, has been made freely available, dedicated to the public domain. Code from the game client is included to help developers work with the assets. All of it can be downloaded and used by anyone, for any purpose. (But: use it for good.)"

Huge collection of arts. Don't miss it!

The Last Door Game Assets


"Hey pals! We have a special gift for you! Today, in commemoration of Alan Turing, father of modern computing, all of Season One's assets will become open source! Also, we want to commemorate you, as the great community we proudly have. Thank you so much! Now you can create your own 'The Last Door' content by using the original graphics and sounds! Create videos, animate gifs or develop your won 'The Last Door' game! The assets are under Creative Commons Attribution 4.0 license, so you can spread your passion in all formats and ways."


"Hi! I'm Davit Masia, I create a lot of graphics for fun, mockups,etc... that usually ends lost on my folders. So i decided upload and share with everybody all that stuff so people can use in their projects. Assets are free but any donation will be welcomed and motivate me to add more and more"

Around 30MB of free arts.



"The assets in this repository are created at Sparklin Labs by Pixel-boy.
They are released under the Creative Commons Zero (CC0) license.

You can use the assets found in this repository in your own games, even commercial ones. Attribution is not required but appreciated. Placing a link to http://superpowers-html5.com/ somewhere would be awesome :)"


"GameArt2D.com is a place to buy royalty free 2D game art assets. It contains more than 50 items, from platformer & top down tileset, side scrolling & top down character spritesheet, game GUI, space shooter asset, and many more.

Who's the guy behind this site?
I'm Zuhria Alfitra a.k.a pzUH. A lone wolf indie-gamedev-wannabe from Yogyakarta, Indonesia."


Huge collection of cliparts, images of animals, plants, education, shapes etc. It can be very helpful to make a derivative art. Get a simple shape and enhance it to something more beautiful. ~1GB of images. Public Domain.


"Unlimited Commercial Use

We try to make it clear that you may use all clipart from Openclipart even for unlimited commercial use. ... We use the Creative Commons Zero 1.0 Public Domain License every time an artist uploads a piece of clipart to Openclipart to make it clear the artist is releasing the creative work for anyone to use for any reason, even commercially."


Very good collection of collections!. This is a MUST visit page. However the repository is big and sometimes you might want to download only few folders from github. For example we want to download a CC0 or non GPL licensed assets. If you know how to use command line then a single folder can be exported from github. GUI based software can also do that.

For example you want to download https://github.com/saniv/free-game-art-unsorted/tree/master/oblique/DCGames_stuff folder but there is no option on that page. Start command shell like bash on Linux or cmd.exe on Windows. Install SVN subversion software and run this command -

Firstly copy the link


Then replace tree/master by trunk. It becomes like this -


Now run

svn export https://github.com/saniv/free-game-art-unsorted/trunk/oblique/DCGames_stuff

This will download only the DCGames_stuff folder. If you don't like command line then try a GUI software like TortoiseSVN and export the url above as example.


Freebies license:

"You are permitted to use the resources in any number of personal and commercial projects for yourself or a client.
You can modify the resources according to your requirements and include them into works such as websites, applications, printed materials and others."


Blender Texture Disc

Public domain textures pack in a CD.

Sweet home 3D texture packs


Contains some useful texture packs.


Owned by Sujit Yadav. He has shared some useful vector arts.

To get more images and textures one can use public domain or CC0 like licensed photos or videos.

3D models:


"Hi there. 'Free the models' is a site dedicated to provide free content for 3d applications and 3d/game engines. The license of the content is that what you download from here is one step away from public domain. So, everything you download from here is free for any use EXCEPT it cannot be included in another free web or cd collection and it cannot be sold separately. Otherwise you can use it in your commercial game, 3d application or render work. You don't have to provide credit but It would be nice if you do. Thank you. Elias Tsiantas /Herakleion/Greece."


Lots of 3D models in sh3f format. Its like zip file and can be extracted.

Free Sounds:


A very useful and huge collection of high quality audios. Below are some sound files i downloaded from this website.

[99Sounds] 99 Drum Samples
[99Sounds] Atmospherik Mekanisms
[99Sounds] Cinematic Sound Effects
99Sounds Drones
[99Sounds] InterSpace
[99Sounds] Magnetic Fields
[99Sounds] Percussa Toolbox by Richard Gould
[99Sounds] Project Exodus
[99Sounds] Project Pegasus
[99Sounds] Punching Percussion
99Sounds Radiophonic Atmospheres by Red Sky Lullaby
[99Sounds] Rain And Thunder
[99Sounds] Sound Design Tools
[99Sounds] The Warehouse

The files are very big and i have compressed them to very low size still maintaining quality. Due to their license restriction i cannot share those compressed ogg files. Please visit their site and download them all. Many of these audio have 96KHz sample rate. Do read the download resume technique at end of this article to download from this site because the big files many times stop resuming.


Various licenses and huge collection of user submitted sounds.


Another good site i used.
Search "free sounds" on Google. There are many sites like this.

Get sound samples from sound pack formats

One best way to get sounds is packed, synth sound formats. Sound formats like SoundFont SF2, Downloadable Sound DLS, Patch (pat files). There are many sites which offer these files. Below are some valuable sound collections or packs.


Big collection of sound sample. Uncompressed size 844 MB

DrumKits from Hydrogen DrumMachine app

The drumkit files are zip files with sample configuration. Extract audio files from them and use in any DAW. Drumkits names:

3355606kit, ColomboAcousticDrumkit, HardElectro1, Synthie-1, BJA_Pacific, DeathMetal, HipHop-1, TD-7kit, Boss_DR-110, EasternHop-1, HipHop-2, Techno-1, circAfrique v4, ElectricEmpireKit, K-27_Trash_Kit, TR808909, Classic-626, ErnysPercussion, Millo-Drums_v.1, VariBreaks, Classic-808, ForzeeStereo, Millo_MultiLayered2, YamahaVintageKit


Many free sound samples.

Download some free Digital Audio making software and many of them offer free sound packs inside them. Linux Multimedia Studio is among them. Download tracker music software and their XI instruments which can be converted to wav or flac.

List of CC0 websites for images, wallpapers, photos



"The Metropolitan Museum of Art makes 375,000 images of public domain art freely available under Creative Commons Zero"

As it says huge collection of museum art can be used for even commercial purpose. Deriving these arts to make new things can be very useful.

How to get more multimedia assets with lesser effort?

I spent lot time in learning programming, music, sound effects, digital arts and some more skills. Now i can make games alone. However i realized one must rather invest time in one skill they love most and Master that skill ( I love all but music is at top :) ). What about those technologies where skill is not enough to complete a work faster? There are many ways to do it. You can pay to a freelancer and get your work done. What if you don't have much money?. This is where free stuff comes to help. Some very useful links have been shared above. But now i will share techniques to get free stuff with little effort.

A video is a sequence of pictures. Therefore an open licensed movie is also bundle of same license image assets. With this idea i downloaded open source videos like BigBuckBunny. ElephantsDream, Sintel etc. There are lots of effects, textures, sounds etc in these videos. Extract data from these videos and use them wherever needed. But don't forget to follow the license honestly!.

Here are links of some public domain, Creative Commons videos:

Blender Movies:







There are many resources which are public domain but can still cause copyright issues. For example old SuperMan cartoons are public domain but the SuperMan himself is not!. Please be careful for these type of things.

How to resume downloads which expires if stopped?

Many websites generate download links which expire after some time or fail if multiple connections are created. I use UGET on linux. Windows version of this software is also available. Simply add a URL and start downloading. When a new url is created go to properties of the download item and replace the old url by new url. Another way is to use KGET. Its also a Linux app. It can add mirror links. Add whenever a new link is created.

Download link:

The links shared here can be very helpful to many indie and non-indie developers. Please submit links in comments i will add here.

Friday, February 3, 2017

Android Video ads and WRITE_EXTERNAL_STORAGE permission

Video ads are getting more and more popular and useful for both developers and publishers. However videos require more network data and disk space to work. Many AdNetworks require external storage write permission to cache videos so that many apps can utilize it.

I just integrated Unity3D, Vungle (more AdColony, AppLovin, InMobi etc later) ad networks for rewarded videos in my game SketchVania. While testing i got issues with external storage write permission. From Marshmallow runtime permission is mandatory and WRITE_EXTERNAL_STORAGE has been added into dangerous Or higher priority permission. One must be ready to handle if permission is denied. After reading setup guide of many ad-networks i found below setting was used by many of them -


This setting means Android will allow WRITE permission upto API 18. Above this API or from KitKat no such permission will be granted. This setting comes from a very important reason. To save internal memory Android Context has methods getExternalCacheDirs(), getExternalFilesDir() etc. These methods allow app's private files to be created in external storage which are deleted after APK is uninstalled. But before KitKat these methods required WRITE_EXTERNAL_STORAGE permission. However this permission resulted into full write access to external storage. This is obviously very bad idea!. Therefore from KitKat using internal architectural changes write permission to /{EXTERNAL_STORAGE}/Android/data/{app_package}/[files,cache] was granted by default.

But there is a serious problem. I was testing my game on XIAOMI REDMI Note 3G and i found using android:maxSdkVersion="18" resulted into NO permission to getExternalFilesDir() etc methods. Whereas the Android documentation says from KitKat these methods don't need write permission. This is inconsistent due to poor or non-standard implementation by manufacturers!. It was causing IOException. This means if you are using maxSdkVersion="18" then chances are high on many Android 4.4 or 18+ API devices using getExternalFilesDir() like methods may not work. In my game i was saving game stats in this directory and nothing was getting saved!. Solution is to simply avoid using max sdk version and use internal cache and files like getCacheDir(), getFilesDir(). However this issue was fixed and most of ROMs today allow access to getExternalCacheDirs() etc without write permission. You may want to dynamically check write permission and handle files. This issue is a lesson that depending on manifest settings can be problematic in future.