Soundboard Challenges

A while back during January this year I released a soundboard app on play store called joker soundboard.I decided to release the app has two versions a free one with 30 sounds and a paid one with 50 different sounds from the movie dark knight rises.

The code was pretty simplistic >>

  • make a list<int> of all the names and location of assets files and a different list<string> of all the dialogues displayed in the scroll-view.
  • Create a list builder function to add all the dialogue strings array to a list view.
  • I got some open source sound play-back libraries from GitHub.
  • Create long onPress and simple onPress function to trigger sound playback by syncing both the asset arrays.
  • implement the admob sdk.

BUT there was a problem . I wanted to share the mp3. files on the long onPress function callback. unfortunately android sdk does not have have any pre-built methods to share files from assets or res folder using share intent method.So there were three solutions >>

  • Create a Content provider myself to serve files from res/ folder to a URI.
  • Use google’s existing file provider method to do the same.(only works on asset files)
  • First copy the files from the res folder to app’s internal directory and there share it using share intent.

All of these three were time consuming and somewhat complex to build methods and due to lack of time I resorted to upload all the mp3s to a google drive  account and sharing the downloadable urls in the share intent method.

The app was a success but many users complained about the lack of direct mp3 sharing feature.

Also, I experienced something rather common among developers, the paid app was getting a number of refunds but the app users weren’t going down. There was something fishy. I concluded that > the trolls are buying the app > creating apk > then refunding the purchase > then reinstalling the apk. The solution to all of this was – IN APP PURCHASES.

Now came the time when I started developing the Thanos soundboard app.This time I decided to resolve all the Issues the joker app had.

1. Implementing MP3 Sharing

I needed a simple yet efficient way to share the mp3 files from my res folder so I started searching through the corners of stack overflow. And hell lot of answers pointed out that I should use android.resource/// <package_name>/raw/file_name to specify the URI for sharing. But this didn’t worked. AT ALL. So I started figuring out why. Apparently android. resource/// method of supplying uri value is nearly obsolete since Noughat release and very few app can use this method. My target sdk was oreo(api 21) and my test device was also running latest build of oreo . So I needed another solution.

Then I stumbled across CWAC.provider library whose tagline was literally :

This is the best Content Provider Library.PERIOD.

It took me some time to understand the mechanics of this lib but the documentation was clear and precise(a little too precise I would say). But when It worked it worked like a charm !

2. Implementing the in app purchases.

This was the most frustrating part of the project. Google’s documentation on implementing the vending and in-app billing is nearly non-existent. All the tutorials and stuff¬† ask you to add this messy example project to your app and then do some magic to get it to work. The problem is that this example project is old and is nearing obsolesce. The code is messy and the libraries are difficult to understand. I spent nearly six hours trying to implement IAPs through this method with no stint of success. And then with the grace of open-source , I found this truly divine library. Holy shit implementing this was a breeze.

And then came another issue!

The DF-AA-20 error.

This issue was fixed by launching the app(not saving apk as a draft but actual launching) first in alpha production level.> making another google account and logging it in my debug device > Adding that account to the testers list > Exempting that account from IAPs.

There was a silver lining to all this DF-AA-20 madness though. I learned about launching a closed tested alpha and an open public beta of my app before the actual roll-out to production !

3. Shared preferences madness.

Note to myself: No matter what any resource tells you. You are always going to implement shared preference this way:

Getting value :

Boolean p_member = getSharedPreferences(“PREFERENCE”, MODE_PRIVATE)
.getBoolean(“Pro_Member”, false);

Setting value :

getSharedPreferences(“PREFERENCE”, MODE_PRIVATE).edit()
.putBoolean(“Pro_Member”, true).commit();

Please remember and save you time ,energy and brain cells by using shared preferences this way.