IPOD Development Doc
💫 Github
> Read Songs From Phone Part - 1
1. Download the TabLayout. Tip1, Tip2
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:id="@+id/tab_layout"
app:tabIndicatorFullWidth="true"
app:tabIndicatorGravity="center"
app:tabTextColor="@color/colorAccent"
app:tabIndicatorHeight="40dp"
app:tabIndicatorColor="#009688"
app:tabIndicator="@drawable/tab_indicator"/>
2. ViewPager
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:id="@+id/tab_layout"
app:tabIndicatorFullWidth="true"
app:tabIndicatorGravity="center"
app:tabTextColor="@color/colorAccent"
app:tabIndicatorHeight="40dp"
app:tabIndicatorColor="#009688"
app:tabIndicator="@drawable/tab_indicator"/>
3. Viewpageradapter
public static class ViewPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments;
private ArrayList<String> titles;
public ViewPagerAdapter(@NonNull FragmentManager fm) {
super(fm);
this.fragments = new ArrayList<>();
this.titles = new ArrayList<>();
}
void addFragments(Fragment fragment, String title){
fragments.add(fragment);
titles.add(title);
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
4. New songsFragment.xml and albumFragment.xml
5. New tabindicator.xml to initialize its style
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:centerColor="@color/colorPrimaryDark" android:angle="0"/>
</shape>
> Read Songs From Phone Part - 2
1. Add permission in MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permission();
}
private void permission() {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE);
}
else
{
musicFiles = getAllAudio(this);
initViewPager();
}
}
2. Add permission in AndroidMainfest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3. Add onRequestPermissionsResult() in MainActivity.java
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
//Do whatever you want permission related;
musicFiles = getAllAudio(this);
initViewPager();
}
else
{
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE);
}
}
}
4. New io.wriprin.android.ipod.MusicFiles.java to pack attributes of songs
5. Add ArrayList getAllAudio
public ArrayList<MusicFiles> getAllAudio (Context context)
{
ArrayList<MusicFiles> tempAudioList = new ArrayList<>();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection =
{
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATA, //for path
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media._ID
};
Cursor cursor = context.getContentResolver().query(uri,projection,null,null, order);
if (cursor != null)
{
while (cursor.moveToNext())
{
String album = cursor.getString(0);
String title = cursor.getString(1);
String duration = cursor.getString(2);
String path = cursor.getString(3);
String artist = cursor.getString(4);
String id = cursor.getString(5);
MusicFiles musicFiles = new MusicFiles(path, title, artist, album, duration, id);
//take log.e for check
Log.e("Path:" + path, "Album" + album);
tempAudioList.add(musicFiles);
if (!duplicate.contains(album)) {
albums.add(musicFiles);
duplicate.add(album);
}
}
cursor.close();
}
return tempAudioList;
}
6. Global Declaration the MusicFiles to use it when user choose allow permission
> Read Songs From Phone Part - 3
1. New layout resource files - music_items.xml to display the SongList
2. New io.wriprin.android.ipod.MusicAdapter.java collect the info
3. Import Glide dependency to build.gradle (Module: app)
//Glide
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
4. songsFragment.java - recyclerview match Adapter
> Read Songs From Phone Part - 4
1. Add the Vector Assest which under drawable and change to a suitable color.
2. New io.wriprin.android.ipod.PlayerActivity(EmptyActivity)
3. New (Drawable Resource File ) - main_bg.xml
4. New (Drawable Resource File ) - gradient.xml
5. Add FloatingActionButton in activity_player.xml
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/play_pause"
android:src="@drawable/ic_play"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:focusable="true"
android:clickable="true"/>
> Read Songs From Phone Part - 5 | PlayAudio
Commit the FUNC of itemview.click
1. Add itemview.click in MusicAdapter.java
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, PlayerActivity.class);
intent.putExtra("position",position);
mContext.startActivity(intent);
}
});
2. Add TimeLine’s layout in activity_player.xml
3. Implement the Init FUNC of PlayerActivity.java
4. MusicAdapter.java to add intent.putExtra()
intent.putExtra("position",position);
5. PlayerActivity.java get the position from MusicAdapter.java
position = getIntent().getIntExtra("position",-1);
6. Implement the method of playing
private void getIntentMethod() {
position = getIntent().getIntExtra("position",-1);
String sender = getIntent().getStringExtra("sender");
if (sender != null && sender.equals("albumDetails"))
{
listSongs = albumFiles;
}
else
{
listSongs = mFiles;
}
if (listSongs != null)
{
playPauseBtn.setImageResource(R.drawable.ic_pause);
uri = Uri.parse(listSongs.get(position).getPath());
}
if (mediaPlayer != null)
{
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = MediaPlayer.create(getApplicationContext(), uri);
mediaPlayer.start();
}
else
{
mediaPlayer = MediaPlayer.create(getApplicationContext(), uri);
mediaPlayer.start();
}
seekBar.setMax(mediaPlayer.getDuration() / 1000);
metaData(uri);
}
7. Implement the timeline_Durationbar and FortmattedTime
runOnUiThread Thread collocate with Handler