Create a simple MP3 player in Android
In this post, you will learn to create a simple MP3 player in Android devices. Many interesting subjects in Android are involved while creating a simple MP3 player. Such as Cursor,ListView, Customized List View Adapter, SeekBar, Thread, MediaPlayer and Runtime permission for Marshmallow 6.0.
I am going just write the codes here. This post is suitable for Basic and Intermediate level android programmers.
I am going just write the codes here. This post is suitable for Basic and Intermediate level android programmers.
MainActivity.java
public class MainActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener { ListSongPath=new ArrayList<>(); List SongNames=new ArrayList<>(); List AlbumNames=new ArrayList<>(); List AlbumDuration=new ArrayList<>(); List AlbumArts=new ArrayList<>(); public static final int MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE=1; String [] sngPath,sngName,AlbName,sngduration; Integer[] AlbumImages; static String TAG; String SongPosition; long mSongDuration; MediaPlayer mp; ImageButton play; ListView listView; SeekBar seekBar; TextView SongProgress,SongMaxLength; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); showSongsList(); seekBar=(SeekBar)findViewById(R.id.seekBar); SongProgress=(TextView)findViewById(R.id.textView4); SongMaxLength=(TextView)findViewById(R.id.textView5); } //creating a method to show songs list only if permission is granted public void showSongsList(){ if(ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){ if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_EXTERNAL_STORAGE)){ }else{ ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE); } }else{ //Getting songs from cursor getSongs(); //Converting List to String[] sngPath=SongPath.toArray(new String[SongPath.size()]); sngName=SongNames.toArray(new String[SongNames.size()]); AlbName=AlbumNames.toArray(new String[AlbumNames.size()]); sngduration=AlbumDuration.toArray(new String[AlbumDuration.size()]); //Showing collected data from cursor using listView listView=(ListView)findViewById(R.id.list); CustomListAdapter adapter=new CustomListAdapter(this,sngPath,sngName,AlbName,sngduration,AlbumImages); listView.setAdapter(adapter); //Creating a method to play selected song. getSelectedSong(); mp = new MediaPlayer(); mp.setAudioStreamType(AudioManager.STREAM_MUSIC); mp.setOnPreparedListener(this); PrepareMediaPlayer(); Log.d(TAG,"OnCreate service"); play=(ImageButton)findViewById(R.id.imageButton); play.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mp.isPlaying()) { mp.pause(); play.setImageResource(R.mipmap.ic_pause_circle_outline_black_24dp); ImageView img=(ImageView)findViewById(R.id.imageView); img.setImageResource(R.mipmap.ic_play_circle_outline_black_24dp); } else { mp.start(); } play.setImageResource(R.mipmap.ic_play_circle_outline_black_24dp); } }); } } //Once User responds to RequestRunTimePermission() method, output executed by the below method. @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode){ case -1: //hello break; case MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE: if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){ showSongsList(); } else{ Toast.makeText(getApplicationContext(),"You've denied permission",Toast.LENGTH_LONG).show(); }return; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } //A method for getting Track name and Album name using cursor. public void getSongs(){ try{ ContentResolver contentResolver=getContentResolver(); Uri uri=EXTERNAL_CONTENT_URI; Cursor cursor=contentResolver.query(uri,null,MediaStore.Audio.Media.IS_MUSIC + " =1",null,null); if(cursor != null && cursor.moveToFirst()){ int songname=cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME); int songalbum=cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM); int songpath=cursor.getColumnIndex(MediaStore.Audio.Media.DATA); int songduration=cursor.getColumnIndex(MediaStore.Audio.Media.DURATION); do{ String CurrentSongPath=cursor.getString(songpath); String CurrentSongName=cursor.getString(songname); String CurrentSongAlbum=cursor.getString(songalbum); String CurrentSongDuration= cursor.getString(songduration); String AlbumId=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)); SongPath.add(CurrentSongPath); SongNames.add(CurrentSongName); AlbumNames.add(CurrentSongAlbum); AlbumDuration.add(CurrentSongDuration); AlbumArts.add(Integer.valueOf(AlbumId)); }while(cursor.moveToNext()); }cursor.close(); }catch(NumberFormatException e){e.printStackTrace();} } //Creating a method for songs selection public void getSelectedSong(){ listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { SongPosition= String.valueOf(listView.getItemAtPosition(i)); ImageView img=(ImageView)view.findViewById(R.id.imageView); img.setImageResource(R.mipmap.ic_equalizer_black_24dp); play.setImageResource(R.mipmap.ic_pause_circle_outline_black_24dp); mp.reset(); PrepareMediaPlayer(); TextView txtview=(TextView)view.findViewById(R.id.textView6); mSongDuration= Long.parseLong(txtview.getText().toString()); } }); } //creating a method for playing a song. public void PrepareMediaPlayer(){ if(SongPosition==null){ Log.d(TAG,"Nothing Selected from the list"); }else { try { Log.d(TAG, "setAudioStreamType"); mp.setDataSource(SongPosition); Log.d(TAG, "setDataSource"); mp.prepareAsync(); Log.d(TAG, "prepareAsync"); } catch (IOException e) { } catch (IllegalArgumentException e) { } catch (IllegalStateException e) { } } } @Override public void onPrepared(MediaPlayer mediaPlayer) { mp.start(); getDurationTimer(); getSeekBarStatus(); } //Creating duration time method public void getDurationTimer(){ final long minutes=(mSongDuration/1000)/60; final int seconds= (int) ((mSongDuration/1000)%60); SongMaxLength.setText(minutes+ ":"+seconds); } //creating a method for seekBar progress public void getSeekBarStatus(){ new Thread(new Runnable() { @Override public void run() { // mp is your MediaPlayer // progress is your ProgressBar int currentPosition = 0; int total = mp.getDuration(); seekBar.setMax(total); while (mp != null && currentPosition < total) { try { Thread.sleep(1000); currentPosition = mp.getCurrentPosition(); } catch (InterruptedException e) { return; } seekBar.setProgress(currentPosition); } } }).start(); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { int progress=0; @Override public void onProgressChanged(final SeekBar seekBar, int ProgressValue, boolean fromUser) { if (fromUser) { mp.seekTo(ProgressValue);//if user drags the seekbar, it gets the position and updates in textView. } final long mMinutes=(ProgressValue/1000)/60;//converting into minutes final int mSeconds=((ProgressValue/1000)%60);//converting into seconds SongProgress.setText(mMinutes+":"+mSeconds); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } }
CustomListAdapter.java
public class CustomListAdapter extends ArrayAdapter{ private Activity context; private String[] Path; private String[] Track; private String[] Description; private String[] Duration; private Integer[] AlbumImage; public CustomListAdapter(Activity context,String[] Path ,String[] Track, String[] Description,String[] Duration,Integer[] AlbumImage){ super(context,R.layout.list_item,R.id.textView,Path); this.context=context; this.Path=Path; this.Track=Track; this.Description=Description; this.Duration=Duration; this.AlbumImage=AlbumImage; } private class ViewHolder{ TextView path; TextView track; TextView description; TextView duration; ImageView imgview; } @NonNull @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; LayoutInflater inflater=context.getLayoutInflater(); if(convertView==null){ convertView=inflater.inflate(R.layout.list_item,null); holder=new ViewHolder(); holder.path=(TextView)convertView.findViewById(R.id.textView); holder.track=(TextView)convertView.findViewById(R.id.textView2); holder.description=(TextView)convertView.findViewById(R.id.textView3); holder.duration=(TextView)convertView.findViewById(R.id.textView6); holder.imgview=(ImageView)convertView.findViewById(R.id.imageView); //store the data in view convertView.setTag(holder); } else{ //we've just avoided calling findViewById() on resource everytime //just use view holder holder=(ViewHolder)convertView.getTag(); } holder.path.setText(Path[position]); holder.track.setText(Track[position]); holder.description.setText(Description[position]); holder.duration.setText(Duration[position]); holder.imgview.setImageResource(R.mipmap.ic_album_black_24dp); return convertView; } }
create an xml for customlistadapter
list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="90dp" android:layout_height="60dp" app:srcCompat="@mipmap/ic_launcher" android:contentDescription="Image" android:id="@+id/imageView" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignTop="@+id/textView" /> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18dp" android:id="@+id/textView2" android:layout_marginLeft="32dp" android:layout_marginStart="32dp" android:layout_below="@+id/textView" android:layout_toRightOf="@+id/imageView" android:layout_toEndOf="@+id/imageView" /> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="13dp" android:textSize="0dp" android:id="@+id/textView" android:layout_alignParentTop="true" android:layout_alignLeft="@+id/textView2" android:layout_alignStart="@+id/textView2" /> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView2" android:layout_toRightOf="@+id/textView" android:layout_toEndOf="@+id/textView" android:id="@+id/textView3" /> <TextView android:text="TextView" android:textSize="0dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/imageView" android:layout_alignLeft="@+id/textView3" android:layout_alignStart="@+id/textView3" android:id="@+id/textView6" /> </RelativeLayout>
activity_main.xml(portrait)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:background="#909090" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.cerebri.learning2.MainActivity" android:weightSum="1"> <ImageButton android:layout_width="80dp" android:layout_height="80dp" android:scaleType="fitXY" android:background="#909090" app:srcCompat="@mipmap/ic_play_circle_outline_black_24dp" android:id="@+id/imageButton" android:layout_above="@+id/seekBar" android:layout_centerHorizontal="true" /> <SeekBar android:layout_width="290dp" android:layout_height="wrap_content" android:maxWidth="3dp" android:maxHeight="3dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginLeft="35dp" android:layout_marginStart="35dp" android:layout_marginBottom="34dp" android:id="@+id/seekBar" /> <TextView android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginStart="16dp" android:layout_marginBottom="12dp" android:id="@+id/textView4" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/textView4" android:layout_alignRight="@+id/list" android:layout_alignEnd="@+id/list" android:id="@+id/textView5" /> <ListView android:layout_width="match_parent" android:layout_height="350dp" android:id="@+id/list" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> </RelativeLayout>
activity_main.xml(Landscape)
just copy and paste the same activity_main.xml file into Layou-land folder under res and design xml file according landscape view.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#909090" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.cerebri.learning2.MainActivity" android:weightSum="1"> <ImageButton android:layout_width="80dp" android:layout_height="80dp" android:scaleType="fitXY" android:background="#909090" app:srcCompat="@mipmap/ic_play_circle_outline_black_24dp" android:id="@+id/imageButton" android:layout_above="@+id/seekBar" android:layout_centerHorizontal="true" /> <ListView android:layout_width="match_parent" android:layout_height="130dp" android:id="@+id/list" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <SeekBar android:layout_width="450dp" android:layout_height="wrap_content" android:id="@+id/seekBar" android:maxHeight="3dp" android:maxWidth="3dp" android:layout_marginBottom="30dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> <TextView android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginLeft="23dp" android:layout_marginStart="23dp" android:layout_marginBottom="10dp" android:id="@+id/textView4" /> <TextView android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/textView4" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginRight="38dp" android:layout_marginEnd="38dp" android:id="@+id/textView5" /> </RelativeLayout>
AndroidManifest.xml
Make sure you add the highlighted things.<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:configChanges="screenLayout|screenSize" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
Comments
Post a Comment