a.k.a: Converting a Native Android App to Sencha Touch: Part 2
If you’re unfamiliar with this series, I’m converting an Android app I originally coded natively in Java to Sencha Touch – if you’d like you can follow along from the start here.
Good news and bad news ahead
Getting the users own music to play from their music library was a big stumbling block for me but eventually I was able to get it to work for Android devices but not iOS. The information on how to do this with PhoneGap and the File API is very sparse, and it took me quite a while to figure out a solution. There was plenty of information on how to play a sound or mp3 file with PhoneGap, which is pretty straight forward, but not how to grab the users own music. So, I figured Part 2 deserved it’s own blog post to save anyone else who wants to do this on Android the hassle in the future. If you want to do it on an iPhone or iPad though, you’re out of luck for now – make sure you come back and tell me if you ever figure it out. Let’s get right into how to do it on Android.
1. Set up a global array
I built the song list from the users library once the device ready event is triggered, and I wanted this to be available everywhere in the application so I set up a global array. To do this in Sencha Touch, go into your launch function in app.js and add the following code:
runtap.globals = {
songList: new Array(),
currentMedia: 'null',
};
Of course, replace ‘runtap’ with the name of your application.
2. Build the song playlist
To grab the mp3 files with the PhoneGap File API the process goes something like this: Request the file system, get the music directory, read the entries and if it is an mp3 add it to the global array. Here’s how to do it, I placed this code in my index.html file after the inclusion of phonegap.js:
<script>
document.addEventListener('deviceready', function () {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
}, false);
function onFileSystemSuccess(fileSystem) {
fileSystem.root.getDirectory("Music", {create: false, exclusive: false}, getDirSuccess, fail);
}
function getDirSuccess(dirEntry) {
var directoryReader = dirEntry.createReader();
directoryReader.readEntries(readerSuccess,fail);
}
function readerSuccess(entries) {
var i;
for (i=0; i<entries.length; i++) {
if(entries[i].name.indexOf(".mp3") != -1){
runtap.globals.songList[i] = entries[i].fullPath;
}
}
}
</script>
Also, make sure you’ve included the File API plugin if you’re using PhoneGap build, that is:
<gap:plugin name="org.apache.cordova.file" />
3. Play a song
Since I couldn’t get this working in iOS I stopped before completely finishing the music playing functions, but essentially all you need to know is that you can play a song from your array using the following code:
runtap.globals.currentMedia = new Media(runtap.globals.songList[2]);
runtap.globals.currentMedia.play();
and to pause it simply:
runtap.globals.currentMedia.pause();
Every time a door closes and all that…
Whenever I can’t get past a problem I try to think of a different way I could approach it, rather than burning myself out and giving up. Since I can’t (I assume) get music to play on both iOS and Android, what options do I have? One other option is to play music the user does not already have on their device. I started to think if I could integrate the application with an online music service like Spotify or Pandora, then I remembered Phil Merrell made a post on including the SoundCloud API in a Sencha Touch application. Perfect. Although I started looking for an easier / alternate way out of this problem, I think this may end up making the application more fun for users. I’m unsure on exactly what the SoundCloud API can do right now, but I plan on allowing users to pick a genre and play random tracks from within that genre (with a focus on more upbeat songs for running of course).
Stay tuned for Part 3 of this series, if you want to know when it’s released then pop your email address into the box on the left and I’ll let you know.
UPDATE: Part 3 is up, you can check it out here.