Hello and welcome to this new Android Development Tutorial. This is part one on how to make a music player for Android. Let’s start. We begin by opening Android Studio, then we will click on start a new Android Studio project, then we’ll click on empty activity, and then on the next button.
As the name of this application, we will write ‘Music Player’. We have the name. Make sure that the language you select is Java and the minimum API level this time we will select 14. Of course, we can change this later if we need to.
We will click on finish and we will wait for the IDE to setup our Android Studio project. The Android studio project is now being set up by the Android Studio IDE so we will wait for it. I will also want to tell you that I will be running the application on an emulator in the left side of the screen.
You can do it in an emulator too if you want or you can actually run it on a real android device. What we have to do in this music player application is actually pretty simple. We need to read the storage of the device and find music files, and then list them on a list view with its respective adapter. Then we will enable the user to play those files .
If you will enjoy reading and contributing to the discussion for this post, will you please join us on the YouTube video above and leave a comment there because I read and respond to most comments on YouTube?
If you find anything helpful in this video or funny, will you please leave a like because you will feel great helping other people find it?
The IDE has finished loading the project and the first thing we will do is we will change the layout file that comes as default.
We’ll go to the left side, we will open the res folder, and then we will open the layout folder. We will right click on the activity_main.xml file, and we will click on delete. We will make sure these both boxes are unchecked, and then we will click in okay.
The file is being deleted as you can see and what we will do now, we will create a new file but with a different root element. For that, we’ll go again, to the layout folder, we will right click on it, then we will click on a new Layout resource file.
As file name we will write activity main, so the same name it had previously, but on root element we will delete the default value, and we will type linear layout. We will press on OK and we will wait for the IDE to generate a code.
As you can see this is the code the IDE generated. In order for us to actually look at the code you will click on the text view mode right here, and as you can see we have our linear layout ready to be used.
Right now just check if everything works okay. I will send the app to the emulator, and make sure that everything looks as we want. These file will enable us to set up how we want the application to look. This is the XML file, the layout file. The Java file will enable us to set how the application behaves.
The emulator is being initialized right here so we have to wait a couple of minutes for it to boot up, and to run the app. As I was telling you, we have these file which enables us to create the user interface of our Android application, and if we add ids to the elements of these interface we can then retrieve those elements using their ids from the code which is the main_activity.java file right here.
We will wait for the app to run and we will check if it is displaying the right content. I will switch to the emulator right here and I will wait for it to boot up. As you can see it says ‘phone is a starting’.
This emulator is running Android P, Android Pie. Android version 9.0 which is API 28. It’s the latest one as at the time of recording this video. As you can see the app should be almost ready. As you can see there’s two processes running right here which is the Gradle Build running. We have this updating indices.
Let’s see. Now, it’s installing the application. Great. If we go to the emulator we can see that we have our app right here and it’s actually working as we expect.
It’s empty because we haven’t really added anything to it. Right now, we will switch back to the Android studio IDE and what I want to do now is to delete these two bars because we want kind of a cleaner look of our application.
We want it completely widescreen.
To hide those two bars what we will do is we will go under the res folder, and then under values folder, and it will open the styles.xml file.
Right here we can customize the actual theme of the application. For that, we will go inside the styled brackets and we will type item name, and we will type window full screen, and we will set this value to true.
What that is doing it’s hiding the top bar. What we are going to do is, we’re going to hide the title, so you’re going to say is window no title. We will also set this to true.
With these two lines I just wrote we are hiding both of the two bars we saw in the emulator. To check if it works I will run the app again and make sure that it looks as we want. It’s been installed. It’s running right now and as you can see it’s empty. Everything is empty just as I want it to be.
We can move on to Android Studio IDE and we will close this style.xml file. We will open the Gradle script file that will enable us to customize and clean up it a bit more. We will open the second one which is the build.gradle file which is a module app. Make sure you open the second. The one that says module app. We open this and this is kind of an abstraction level in which we set the configuration for our application.
This is a simple application. We are just learning. We can simplify this file a lot more so you can actually by having a simpler view of it, you can actually understand what’s going on.
This line is for testing.
We won’t be testing it with using the unit tester library, so we can delete this line. These brackets – these BuiltTypes bracket – we don’t need it. We don’t need it because we are not deploying it and we don’t have custom configurations for it.
Here are the dependencies.
There’s a lot of stuff that we don’t really need about this. The only one we need is this one – the appcompat library. So we can delete all the others but not that one. We will delete all these. As you can see now the file is a lot more simple and easier to read.
What this is saying basically, is we’re using API 28 to compile the application. The minimum SDK we’re targeting is 14 and the target is 28. The version code of the app is 1 and the version name 1.0. The only dependency we’re using is the appcompat1.
After we have modified these we will click on sync now here at the top. If you don’t find that button you can also click on these elephant button that selected with the mouse pointer.
We can also close this file. To make sure everything works again, I will run the app again and check that it still works fine. Let me see. I’m installing the app and I’m running and it still work fine.
Let’s actually start with the coding of our application.
Great. The first thing we will do is we will work on the layout file of our application. As I told you the layout file enables us to create UI elements using the XML kind of scripting language. After we do that, we can access the code from Java.
Let’s start working on it. We will go to activity_main.xml file and since what we want to do is list the music files or the audio files, kind of mp3 files that exist on the device storage, we will use a ListView.
We will open an element and type ListView.
The width of this element will be match_parent. The height will be 0DP and the weight will be 1. We can close this here to make it more clean to see. We will add an ID to this object, so we’re going to type ID and we will call it ListView.
We have added a list view right here. Apart from listing the music files, we want to kind of, of course, play the music file, and maybe show controls of maybe stop and play the file again. We can implement that later. For now, this is the only thing we will add. Later we can complete this file. We will switch back to our main activity.java and here we will start reading what’s going on.
As default the IDE generates for us this file and adds the onCreate() Method in which the only thing it does is it set the content view to our XML file. We are reading files from this storage – from the device storage – and the Android operating system requires us to ask for permission starting in API 23 or Marshmallow and above.
To ask for permission we will go to our manifest file right here, we will open this.
As you can see, we have a warning. We can ignore that by clicking and suppress the warning if you want.
We also have here the activity definition. The orientation of the activity will be portrait so we going to say screen orientation and set that to portrait.
Apart from that, we will type the application tag and we will open the uses-permission element. The first one will be set to read external storage. We’re reading the external storage right here which is the permission we need in order for our application to run.
Once we have defined the permission on the androidmanifest.xml file, we can go to our main activity.java file and actually start initializing everything we want our application to do. First of all, we have to be able to check permissions at runtime as I told you in Android 23 – apk23 or Marshmallow. We are required to do just that.
To do that we’ll do the following. After the onCreate() method, we will define the permissions we want to ask. For that we’re going to type Private static final_String. We will define the permissions as an array of strings and we will call this PERMISSIONS. Remember to end the line with a semicolon and here we will specify the actual permissions our app requires.
To specify the permissions we will do the following;- we will type manifest.permission.READ_EXTERNAL_STORAGE.
This is the permission we need. It says that field requires API level 16. To fix this warning we will go to our build.gradle file we opened previously. The one we have simplified. We will change the minimum SDK version from 14 to 16.
We will click on sync now, we will wait for the sync to be completed. We can close this file, go back to our main activity.java and we can see that the warning has disappeared which is awesome.
Now, that we have defined the permissions we want, we also want to define a request code, so we can know which permission we requested, and kind of control the flow of the permission request process. To do that we got to say and create the following variable.
Private static final int. We will call this REQUEST_PERMISSIONS. Here we have to enable or assign this int and a kind of a unique ID. It doesn’t really matter. Maybe I will tell it to be one, two, three, four, five. It’s actually any number you want.
Lastly, we have to define a variable an Int variable again, that will store the amount of permissions we are requesting. In this case, it’s just one. We will call this PERMISSIONS _COUNT. We will set this to 1.
As default in some devices the permissions are automatically granted, but in other’s they are not. We will check if the permissions are denied by creating the following method. We’re going to say private boolean arePermissionsDenied. You will open these method and we will create a for loop as follows. We’re going to say for int I=0: I <_PERMISSIONS _COUNT. We will say I++.
We open the For loop and we write the following logic. We will check if the permissions are granted or not. To that we’re going to say if checkSelfPermission and as the parameter we will pass PERMISSIONS at I. We access the string array of the permissions, and we are pointing to the element I. If permissions at I is different, if checkSelfPermission at I is different then PackageManager.PERMISSION_GRANTED. So if it’s different than permission granted, we will return true which will tell us the permission has been denied. After we run this for loop and if it hasn’t returned, we will return false which means permissions are not denied. Which means they are granted.
As you can see we have a warning right here on the check self permissions line which says call requires API level 23, but we will be calling this only in API level 23, so we can ignore this by clicking in this warning sign, and then suppress link new API annotation.
We click on that and this line is added and now, the warning is gone. That’s it for this method here. We will continue right now and after the user checks or clicks on allow or deny permission what we have to do is get the result of that permission. If the user allowed it or denied.
To do that, we will do the following. We will override public void onRequestPermissionsResult(). Inside this, we have some parameters that are passed. The first one will be an int which will pass the requestCode. So you can say int requestCode. The second one will be a string array and we have the permissions we were asking for. So, permissions and we also have an int array that will return the results of those permissions. So we can call it grantResults.
We will open the method and we’ll call the super method. We’re going to say super.onrequestpermissionsresult, and we will pass the same parameters we receive. So the first one will be requestCode then will be permissions, and then will be grantResults. Great.
Now, we can make our lives easier by using the previous method, we wrote which is arePermissionsDenied, so we will check it right here. We’re going to say if arePermissionsDenied this means that the user has denied the permission. If that permission is a must the app cannot work without it. So if the user denies the permission we want to clear the application data, and close the app which will enable us to keep asking for the permission every time the user opens the app again.
To accomplish that, we will do the following. We will open two parentheses and the first one we will write ActivityManager. Outside the first one, we will create another parenthesis. The ActivityManager is kind of the casting object, that we’re casting into. Inside these second parenthesis, we will type this.getSystemService. As the parameter of this we will pass ACTIVITY_SERVICE. We go after the three parentheses and we type .clearApplicationUserData, and this is basically the line that will clear the data right here.
We have ActivityManager, getSystemService(ACTIVITY_SERVICE). We then type clearApplicationUserData. Again, this warning should be silence because we’re calling only when we should. We’re going to go and say suppressLint new API annotation and the warning is gone.
In that case, what we will do is we will recreate the activity after that.
The first record is when the user denies activity, and when the user allows the permission, we want to call the onResume method because in that method we will do all the initialization. We just type on resume and we’ll leave it there.
We have basically created our basic method right here, so now let’s override the onresume method. We’re going to go and say @override protected void onResume. Inside the method we’ll call the super method. Super.onResume and inside here what we will do is we will check if we have to requests or not the permissions.
To do that we will do the following, we’ll go and type if Build.VERSION.SDK_INT >= Build.VERSION_CODES. M which means marshmallow. If this statement is true, we also will check if the permissions are denied. To check the permissions are denied, we will say && arePermissionsDenied. So we call the method. If those two conditions are true we will request for permissions. To do that we going to type requestPermissions and as the first parameter will pass PERMISSIONS which is our array of permissions, and a second one will be the requestCode which is the REQUEST_PERMISSIONS variable.
After this, we will return because we don’t want to keep initializing if we don’t have the required permissions. Right now, we have our basic kind of app that ask permission so to check that everything works as we want, we will run the application to check if it actually works as expected. Now, I’m compiling the app and sending it to the emulator. Emulator runs the app and as you can see it appears this dialog that says ‘Allow music player to access photos, media, and files on your device?’ Here the user can click either deny or allow.
If the user clicks on deny then the app is closed and the application data is cleared. If the user goes again on the music player application it asks again. So the user can keep denying, and keep opening the app. The user can keep opening the app.
Basically what we did in this tutorial is we setup the Android studio project, we simplified the layout file, we simplified the Gradle build file, and we are requesting the permissions in the Android manifest, and also on code. I will run the app again. Click music player. So as you can see it keeps asking until the user allows the permission.
I will click on allow and as you can see now the app stays opened which is great. If we go back to our IDE and we continue looking at the code, we can see on the on resume method on the return, we have a warning right here that says return is unnecessary as the last statement in ‘void’ method which is true but that won’t be the last statement because we will keep writing some stuff here.
What we will do now is start initializing the music player. For that, we will create a global variable that will be private boolean is MusicPlayerInit which means is music player initialized? As default, of course, that will be set to false and right here inside the onResume() method we will check for that flag, so we’re going to type if !isMusicPlayerInit which means if music player is not initialized then we will initialize the music player.
Right here, the first thing we will do is change the flag. The last statement of this if bracket, we will go and say isMusicPlayerInit and we will set this to true. Awesome.
If you remember on the activity_main.xml file we created a ListView so we will access this ListView right now from the Java code. To access the ListView we will do the following. We go and say final ListView and we will call it ListView, and we will set this to find view by Id. R.id.listview. Great. Right now we have created our ListView. We’re accessing this ListView from code which is great.
In the next part we will learn how to set up this ListView and create a parameter.
We will read files and everything else we require to make this app working. In this part we will continue to work on the application. Right now, we go to our onResume() method and here in the check in which we check if the music player is initialized, in the previous part what we did here is that we set the ListView to the element of our manifest file.
The next thing we will do is to actually create an adapter for our ListView. We will go outside the onResume() method and we will type class. We will call this class TextAdapter and we will extend BaseAdapter.
We will open this bracket right here and we will create the following method that will enable us to set the data of the adapter. First of all we will create an array list that will contain the data. For now, we’re going to type private list of strings, and we will call this data, and we’ll set these to new array list. Don’t forget to import the list library.
We have our data array list just created and now we are going to set and create a method that will enable us to set the data of that array list. We’re going to type void setData. We will open these method right here, and what we’ll do is first we will clear the previously data that existed on that array list. For that we’re going to say data.clear. Next what I will do is data.addAll.
What we have to add is the new data so we have to create a new parameter inside setData method definitions. Right here, you can say list of string and we call this mData.
Inside this addAll what we will do is type mData. Great.
After we have updated the data set we were going to notify that it was updated, so you’re going to say notifyDataSetChanged. Great.
That was our setData method. We will continue writing the next method. The first one will override will be the getCount method. We’re going to say override public int get count. We will open this and what we will return that has to be an int will be the size of our data set. So I got to say return data.size.
That’s our getCount method. Next, we will override the getItem method. So we can say @override public object, getItem, and as parameter we will get position.
Instead of object we will actually change this to string because maybe we need to use this if we need it. We will open this method right here and we will return null for now, right? Because I don’t think we will need it for now. Later if we need it we will return what we need.
We have to also override the getItemId method, so you can say public long getItemId. The parameter of these will be int position as well. We will open these and once again, will return null because we won’t be returning anything right here, but we have to override it.
We cannot return null apparently so we will return 0. Great.
That’s getItemId and now, we will override the last method which is also the most important one which is the getView method. Public view, import view library, then call getView. The parameters of this method will be as follows;- the first one int position – the position of the view. The next one will be view convertView – which is the view we’re getting – and the third is the view group, so viewGroup. You will call it parent.
We will open this method and we have to, of course, return a view right here. First of all, we will check if convertView is null in order for us to initialize it. You can say if convertView is null what we’re going to go is going to open this bracket right here, and if it’s null, we will do the following. We will get the view and inflat it but before we do that, we have to actually create that view in code – in XML code actually.
So to do that we will go and open our res folder here at the left side of the screen. Then the layout folder.
We will right click on the layout folder, then on new, and the layout resource file. In file name we will call it item and as root element we will put a text view because we will be displaying text, right? Make sure you have item and text view, and then click in OK.
As you can see the IDE generates this file for us. We will switch to the text mode right here, and we will modify these a bit. As you can see the width and height parameters are already set. We also have to set an ID to these text view items, so we’re going to say ID maybe myItem. We’re going to set the gravity. We want the text to appear in the center so we’re going to say gravity will be set to center vertical.
Then we’re going to kind of change the text size a bit. For this case, I think it would be 20 sps something like that. That’s good. Text size 20 SP. We can change that later, of course. We will also add a padding to the start in order for us to kind of look at it in a more easy way, so we’re going to say padding start. We’re going to set this to 16 DP. Here we’re have a kind of warning that tells us that we should also set padding left, so we will do that too. Padding left we will also set this to 16 DP which is great.
It says that we have also defined padding right and paddingEnd, so we’re going to do that. PaddingEnd again 16 DP and also padding right also 16 DP. As you can see the warnings are now gone. Great.
Now, what we will set the text color to will be black. So I’m going to go and say text color, to set it to black we’re going to write number sign # followed by six zeros and I think we’re ready to go now, right? Awesome.
We will go back to our main activity.java file and we will continue to write our getView method now, that we have created the item on the XML file. If convertView is null what we will do is convert view equals to ayoutInflater.from, we open parentheses and we type parent.getContext. Outside this we’re going to press dot. I will do it in the next line. Get the context.inflate and we will inflate the layout right here, so it will be R.layout.item. That will be the first parameter. The second one will be the parent or the root so we’re going to pass parent, and the third will be attached to root. In this case, we’re going to pass it false.
We have set our convert view variable right here and I will also set the tag that will enable us to get it’ll later when we want to set the text to the view. You got to say convert view.set tag and as the tag we’ve got to say new Viewholder. We don’t have the viewholder so we have to create the viewholder class. You got to go outside this getView method just here. We’re going to type class ViewHolder and inside this method we’re going to do the following. We’re going to create a text view. We’ll call this text view info, for example. You can have any name really and as the constructor method you’re going to say ViewHolder. The parameter, the first one would be the only one actually textview. I’ll call it mInfo and I will open these right here and I will set info is equal to mInfo and that’s it for this class.
We can go back to convertView.setTag line, we were previously, and now we can access the ViewHolder class that we create as you can see. Now right here we will open parentheses after this ViewHolder definition. We’ll open parentheses again to cast in textview and outside this, we will type convertview.findviewbyID, and this ID we will type r.id.myitem.
Right now, that’s it for when the convert view is null. Outside this if bracket we’re going to create a holder . You can say ViewHolder we’ll call this holder and we will cast this to ViewHolder, and we will set this to convertView.getTags. We’re getting the tag we set previously. Here we’re going to get the item that we want to display.
You can say final string, call it item and what we’re going to do is data.get(position). Which is great. We have our item and our holder. We have to now set the text view.
GET MORE OF THIS COURSE
Would you like to continue learning about the Code Your Own Music Player App in Android Studio Course? If you are interested will you please buy the complete course, Code Your Own Music Player App in Android Studio, on the Uthena Education Platform..
Thank you for reading the blog post or watching the course on YouTube.
I love you.
Thank you very much for checking out the Code Your Own Music Player App in Android Studio Course and I hope to see you again in the next blog post or video.