diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/SelectSongFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/SelectSongFragment.kt new file mode 100644 index 0000000..1695b66 --- /dev/null +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/SelectSongFragment.kt @@ -0,0 +1,122 @@ +package com.example.spotifydownloader.Fragments + +import android.app.Activity +import android.os.Bundle +import android.view.View +import android.view.animation.Animation +import android.view.animation.AnimationUtils +import androidx.activity.OnBackPressedCallback +import androidx.core.view.forEach +import androidx.fragment.app.Fragment +import androidx.navigation.NavController +import androidx.navigation.Navigation +import androidx.navigation.fragment.navArgs +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.spotifydownloader.R +import com.example.spotifydownloader.databinding.FragmentSelectSongBinding +import com.example.spotifydownloader.parcels.DataSearch +import com.example.spotifydownloader.rvAdaptors.SongSearchRecyclerViewAdaptor +import com.google.android.material.bottomnavigation.BottomNavigationView + + +class selectSongFragment : Fragment(R.layout.fragment_select_song) { + private lateinit var binding :FragmentSelectSongBinding + private lateinit var navController: NavController + private val args by navArgs() + private lateinit var bottomNav : BottomNavigationView + + + + + + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding = FragmentSelectSongBinding.bind(view) + navController = Navigation.findNavController(view) + bottomNav = activity?.findViewById(R.id.bottomNav)!! + + val rV = binding.rvSongSearch + + val from_top : Animation by lazy { AnimationUtils.loadAnimation((context as Activity), + R.anim.from_top + ) } + val from_bottom : Animation by lazy { AnimationUtils.loadAnimation((context as Activity), + R.anim.from_bottom + ) } + + + val callback = object : OnBackPressedCallback(true){ + override fun handleOnBackPressed() { + navController.popBackStack() + bottomNav.startAnimation(from_bottom) + bottomNav.menu.forEach { + it.isEnabled = true + } + + + } + } + requireActivity().onBackPressedDispatcher.addCallback(callback) + + + bottomNav.startAnimation(from_top) + bottomNav.menu.forEach { + it.isEnabled = false + } + + + val adapter = SongSearchRecyclerViewAdaptor(args.ItemListData.Items) + rV.adapter = adapter + rV.layoutManager = LinearLayoutManager(context) + adapter.setOnItemClickListener(object :SongSearchRecyclerViewAdaptor.onItemClickListener{ + override fun onItemClick(position: Int) { + val regex = Regex("[^A-Za-z0-9]") + val songData = args.ItemListData.Items[position] + + + val data = DataSearch( + songName = songData.name, + imgUrl = songData.album.images[0].url, + artistName = songData.artists[0].name, + filename = regex.replace(songData.name,""), + albumName = songData.album.name, + albumArtistName = songData.album.artists[0].name, + releaseDate = songData.album.release_date, + folderUri = args.ItemListData.folderUri + ) + val action = selectSongFragmentDirections.actionSelectSongFragmentToSongDownloadFragment2(data) + navController.navigate(action) + + + + } + + }) + + + + + + + + + + + + + + + + + + + + + + } + + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt index cc987cd..3f85152 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt @@ -23,7 +23,7 @@ import androidx.navigation.fragment.navArgs import coil.load import com.example.spotifydownloader.R import com.example.spotifydownloader.databinding.FragmentSongDownloadBinding -import com.example.spotifydownloader.model.songItemData +import com.example.spotifydownloader.rvData.songItemData import com.example.spotifydownloader.mp3agic.Mp3File import com.google.android.material.bottomnavigation.BottomNavigationView import com.yausername.youtubedl_android.YoutubeDL @@ -42,12 +42,13 @@ import java.net.URL class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { private var fragmentSongDownload: FragmentSongDownloadBinding? = null private val tag = "MainActivity" - private lateinit var bottomNav : BottomNavigationView private lateinit var navController: NavController private val args by navArgs() private var stop = false private var songItems = mutableListOf() private lateinit var binding:FragmentSongDownloadBinding + private lateinit var bottomNav : BottomNavigationView + @@ -63,17 +64,10 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { bottomNav = activity?.findViewById(R.id.bottomNav)!! - val from_top : Animation by lazy { AnimationUtils.loadAnimation((context as Activity), - R.anim.from_top - ) } + val from_bottom : Animation by lazy { AnimationUtils.loadAnimation((context as Activity), R.anim.from_bottom ) } - bottomNav.startAnimation(from_top) - bottomNav.menu.forEach { - it.isEnabled = false - } - val callback = object : OnBackPressedCallback(true){ override fun handleOnBackPressed() { Toast.makeText((context as Activity),"Stopping...",Toast.LENGTH_SHORT).show() @@ -100,6 +94,7 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { Toast.LENGTH_SHORT ).show() navController.popBackStack() + navController.popBackStack() bottomNav.startAnimation(from_bottom) bottomNav.menu.forEach { it.isEnabled = true @@ -117,6 +112,7 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { Toast.LENGTH_SHORT ).show() navController.popBackStack() + navController.popBackStack() bottomNav.startAnimation(from_bottom) bottomNav.menu.forEach { it.isEnabled = true @@ -135,6 +131,7 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { Toast.LENGTH_SHORT ).show() navController.popBackStack() + navController.popBackStack() bottomNav.startAnimation(from_bottom) bottomNav.menu.forEach { it.isEnabled = true diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt index 753a10d..e52439d 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt @@ -15,16 +15,14 @@ import androidx.navigation.NavController import androidx.navigation.Navigation import com.example.spotifydownloader.R import com.example.spotifydownloader.SpotifyApi.SpotifyApi +import com.example.spotifydownloader.SpotifyApi.model.Search.Item import com.example.spotifydownloader.SpotifyApi.util.Constants.Companion.CLIENT_ID import com.example.spotifydownloader.SpotifyApi.util.Constants.Companion.CLIENT_SECRET import com.example.spotifydownloader.databinding.FragmentSongBinding -import com.example.spotifydownloader.model.DataSearch +import com.example.spotifydownloader.parcels.ItemListData import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async import kotlinx.coroutines.launch import java.io.IOException -import java.lang.NullPointerException - class SongFragment : Fragment(R.layout.fragment_song) { @@ -91,14 +89,9 @@ class SongFragment : Fragment(R.layout.fragment_song) { runOnUiThread { enableDisableUI(false) } - var songName ="" - var imgUrl ="" - var artistName = "" - var filename = "" - var albumName = "" - var albumArtistName = "" - var releaseDate = "" - var succesCode :Int + var succesCode = 0 + val ItemListObject = mutableListOf() + @@ -106,21 +99,16 @@ class SongFragment : Fragment(R.layout.fragment_song) { try { - val textInBox = binding.songNameEditText.text.toString() + val textInBox = "${binding.songNameEditText.text.toString()} ${binding.artistNameEditText.text.toString()}" val response = spotifyApi.getSearch(textInBox) if (response.tracks.items.size !=0) { - val searchResult = response.tracks.items[0] - val regex = Regex("[^A-Za-z0-9]") - songName = searchResult.name - imgUrl = searchResult.album.images[0].url - artistName = searchResult.artists[0].name - filename = regex.replace(searchResult.name, "") - albumName = searchResult.album.name - albumArtistName = searchResult.album.artists[0].name - releaseDate = searchResult.album.release_date + response.tracks.items.forEach { + ItemListObject.add(it) + } + succesCode = 0 } else{ @@ -149,6 +137,7 @@ class SongFragment : Fragment(R.layout.fragment_song) { if (isDeviceOnline(context as Activity)&&data!=null&& succesCode== 0){ + /* val dataToBeSent = DataSearch( songName = songName, imgUrl = imgUrl, @@ -159,7 +148,9 @@ class SongFragment : Fragment(R.layout.fragment_song) { releaseDate = releaseDate, folderUri = data!!.data ) - val action = SongFragmentDirections.actionSongFragmentToSongDownloadFragment(dataToBeSent) + + */ + val action = SongFragmentDirections.actionSongFragmentToSelectSongFragment2(ItemListData(ItemListObject.toList(),data!!.data)) runOnUiThread { enableDisableUI(true) navController.navigate(action) diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/albumFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/albumFragment.kt index 10be0b2..cea1ddd 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/albumFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/albumFragment.kt @@ -17,7 +17,7 @@ import com.example.spotifydownloader.R import com.example.spotifydownloader.SpotifyApi.SpotifyApi import com.example.spotifydownloader.SpotifyApi.util.Constants import com.example.spotifydownloader.databinding.FragmentAlbumBinding -import com.example.spotifydownloader.model.Data +import com.example.spotifydownloader.parcels.Data import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.IOException diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/downloadFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/downloadFragment.kt index 0b82963..3d79d35 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/downloadFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/downloadFragment.kt @@ -23,8 +23,8 @@ import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.LinearLayoutManager import com.example.spotifydownloader.R import com.example.spotifydownloader.databinding.FragmentDownloadBinding -import com.example.spotifydownloader.model.recyclerViewAdaptor -import com.example.spotifydownloader.model.songItemData +import com.example.spotifydownloader.rvAdaptors.recyclerViewAdaptor +import com.example.spotifydownloader.rvData.songItemData import com.example.spotifydownloader.mp3agic.Mp3File import com.google.android.material.bottomnavigation.BottomNavigationView import com.yausername.youtubedl_android.YoutubeDL diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/playListFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/playListFragment.kt index 7c7b715..90cd17b 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/playListFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/playListFragment.kt @@ -18,7 +18,7 @@ import com.example.spotifydownloader.SpotifyApi.SpotifyApi import com.example.spotifydownloader.SpotifyApi.util.Constants.Companion.CLIENT_ID import com.example.spotifydownloader.SpotifyApi.util.Constants.Companion.CLIENT_SECRET import com.example.spotifydownloader.databinding.FragmentPlayListBinding -import com.example.spotifydownloader.model.Data +import com.example.spotifydownloader.parcels.Data import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.IOException diff --git a/app/src/main/java/com/example/spotifydownloader/SpotifyApi/SpotifyApi.kt b/app/src/main/java/com/example/spotifydownloader/SpotifyApi/SpotifyApi.kt index dd5c36e..219fd40 100644 --- a/app/src/main/java/com/example/spotifydownloader/SpotifyApi/SpotifyApi.kt +++ b/app/src/main/java/com/example/spotifydownloader/SpotifyApi/SpotifyApi.kt @@ -241,7 +241,7 @@ class SpotifyApi(private val clientId: String, private val clientSecret: String, } - suspend fun getSearch(query:String):Search{ + suspend fun getSearch(query:String ):Search{ if (authToken == null){ getAuthTokenOrRefresh( clientId = clientId, diff --git a/app/src/main/java/com/example/spotifydownloader/SpotifyApi/api/SpotifyAPI.kt b/app/src/main/java/com/example/spotifydownloader/SpotifyApi/api/SpotifyAPI.kt index 66edf85..a28a0a7 100644 --- a/app/src/main/java/com/example/spotifydownloader/SpotifyApi/api/SpotifyAPI.kt +++ b/app/src/main/java/com/example/spotifydownloader/SpotifyApi/api/SpotifyAPI.kt @@ -43,7 +43,6 @@ interface SpotifyAPI { @HeaderMap headers: Map, @Query("q") searchQuery:String, @Query("type")type:String = "track", - @Query("limit")limit:Int = 1 ):Response diff --git a/app/src/main/java/com/example/spotifydownloader/SpotifyApi/model/Search/Item.kt b/app/src/main/java/com/example/spotifydownloader/SpotifyApi/model/Search/Item.kt index 0dc0971..45c6e92 100644 --- a/app/src/main/java/com/example/spotifydownloader/SpotifyApi/model/Search/Item.kt +++ b/app/src/main/java/com/example/spotifydownloader/SpotifyApi/model/Search/Item.kt @@ -1,13 +1,17 @@ package com.example.spotifydownloader.SpotifyApi.model.Search +import android.os.Parcelable + + + data class Item( - val album: Album, - val artists: List, + val album: Album, + val artists: List, val disc_number: Int, val duration_ms: Int, val explicit: Boolean, - val external_ids: ExternalIds, - val external_urls: ExternalUrlsXXX, + val external_ids: ExternalIds, + val external_urls: ExternalUrlsXXX, val href: String, val id: String, val is_local: Boolean, diff --git a/app/src/main/java/com/example/spotifydownloader/model/Data.kt b/app/src/main/java/com/example/spotifydownloader/parcels/Data.kt similarity index 91% rename from app/src/main/java/com/example/spotifydownloader/model/Data.kt rename to app/src/main/java/com/example/spotifydownloader/parcels/Data.kt index a748316..40b0ef8 100644 --- a/app/src/main/java/com/example/spotifydownloader/model/Data.kt +++ b/app/src/main/java/com/example/spotifydownloader/parcels/Data.kt @@ -1,4 +1,4 @@ -package com.example.spotifydownloader.model +package com.example.spotifydownloader.parcels import android.net.Uri diff --git a/app/src/main/java/com/example/spotifydownloader/model/DataSearch.kt b/app/src/main/java/com/example/spotifydownloader/parcels/DataSearch.kt similarity index 88% rename from app/src/main/java/com/example/spotifydownloader/model/DataSearch.kt rename to app/src/main/java/com/example/spotifydownloader/parcels/DataSearch.kt index 8aa4d01..246aeda 100644 --- a/app/src/main/java/com/example/spotifydownloader/model/DataSearch.kt +++ b/app/src/main/java/com/example/spotifydownloader/parcels/DataSearch.kt @@ -1,4 +1,4 @@ -package com.example.spotifydownloader.model +package com.example.spotifydownloader.parcels import android.net.Uri import android.os.Parcelable diff --git a/app/src/main/java/com/example/spotifydownloader/parcels/ItemListData.kt b/app/src/main/java/com/example/spotifydownloader/parcels/ItemListData.kt new file mode 100644 index 0000000..fd990e3 --- /dev/null +++ b/app/src/main/java/com/example/spotifydownloader/parcels/ItemListData.kt @@ -0,0 +1,13 @@ +package com.example.spotifydownloader.parcels + +import android.net.Uri +import android.os.Parcelable +import com.example.spotifydownloader.SpotifyApi.model.Search.Item +import kotlinx.parcelize.Parcelize +import kotlinx.parcelize.RawValue + +@Parcelize +data class ItemListData( + var Items : @RawValue List, + var folderUri: Uri? +):Parcelable diff --git a/app/src/main/java/com/example/spotifydownloader/model/recyclerViewAdaptor.kt b/app/src/main/java/com/example/spotifydownloader/rvAdaptors/RecyclerViewAdaptor.kt similarity index 91% rename from app/src/main/java/com/example/spotifydownloader/model/recyclerViewAdaptor.kt rename to app/src/main/java/com/example/spotifydownloader/rvAdaptors/RecyclerViewAdaptor.kt index 9d8d3bc..ce38014 100644 --- a/app/src/main/java/com/example/spotifydownloader/model/recyclerViewAdaptor.kt +++ b/app/src/main/java/com/example/spotifydownloader/rvAdaptors/RecyclerViewAdaptor.kt @@ -1,4 +1,4 @@ -package com.example.spotifydownloader.model +package com.example.spotifydownloader.rvAdaptors import android.view.LayoutInflater import android.view.View @@ -9,6 +9,7 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import coil.load import com.example.spotifydownloader.R +import com.example.spotifydownloader.rvData.songItemData class recyclerViewAdaptor (private val songData: List) :RecyclerView.Adapter() { @@ -40,7 +41,7 @@ class recyclerViewAdaptor (private val songData: List) holder.songCoverImage.load(recyclerViewAdaptor.imageUrl) - if (recyclerViewAdaptor.songName.length>19) { + if (recyclerViewAdaptor.songName.length>24) { holder.songTitle.text = recyclerViewAdaptor.songName.take(17).plus("...") } else{ diff --git a/app/src/main/java/com/example/spotifydownloader/rvAdaptors/SongSearchRecyclerViewAdaptor.kt b/app/src/main/java/com/example/spotifydownloader/rvAdaptors/SongSearchRecyclerViewAdaptor.kt new file mode 100644 index 0000000..5ddb993 --- /dev/null +++ b/app/src/main/java/com/example/spotifydownloader/rvAdaptors/SongSearchRecyclerViewAdaptor.kt @@ -0,0 +1,63 @@ +package com.example.spotifydownloader.rvAdaptors + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import coil.load +import com.example.spotifydownloader.R +import com.example.spotifydownloader.SpotifyApi.model.Search.Item + +class SongSearchRecyclerViewAdaptor( private val dataSet:List): + RecyclerView.Adapter() { + + + private lateinit var mListener:onItemClickListener + interface onItemClickListener{ + fun onItemClick(position: Int) + } + fun setOnItemClickListener(listener:onItemClickListener){ + mListener = listener + + } + + + class ViewHolder(view: View,listener:onItemClickListener):RecyclerView.ViewHolder(view) { + val coverImage: ImageView + val songName:TextView + val artistName:TextView + + init { + coverImage = view.findViewById(R.id.songCoverImage1) + songName = view.findViewById(R.id.songTitle1) + artistName = view.findViewById(R.id.artistName1) + + itemView.setOnClickListener { + listener.onItemClick(adapterPosition) + } + + + } + } + + override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { + // Create a new view, which defines the UI of the list item + val view = LayoutInflater.from(viewGroup.context) + .inflate(R.layout.song_search_item, viewGroup, false) + + return ViewHolder(view,mListener) + } + + + override fun getItemCount(): Int = dataSet.size + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.coverImage.load(dataSet[position].album.images[0].url) + holder.songName.text = dataSet[position].name + holder.artistName.text = dataSet[position].artists[0].name + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/spotifydownloader/model/songItemData.kt b/app/src/main/java/com/example/spotifydownloader/rvData/SongItemData.kt similarity index 80% rename from app/src/main/java/com/example/spotifydownloader/model/songItemData.kt rename to app/src/main/java/com/example/spotifydownloader/rvData/SongItemData.kt index b38ff26..c545643 100644 --- a/app/src/main/java/com/example/spotifydownloader/model/songItemData.kt +++ b/app/src/main/java/com/example/spotifydownloader/rvData/SongItemData.kt @@ -1,4 +1,4 @@ -package com.example.spotifydownloader.model +package com.example.spotifydownloader.rvData data class songItemData(val imageUrl : String, diff --git a/app/src/main/res/drawable/baseline_content_paste_24.xml b/app/src/main/res/drawable/baseline_content_paste_24.xml new file mode 100644 index 0000000..fb4f086 --- /dev/null +++ b/app/src/main/res/drawable/baseline_content_paste_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/baseline_search_24.xml b/app/src/main/res/drawable/baseline_search_24.xml new file mode 100644 index 0000000..a5687c6 --- /dev/null +++ b/app/src/main/res/drawable/baseline_search_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_select_song.xml b/app/src/main/res/layout/fragment_select_song.xml new file mode 100644 index 0000000..262b375 --- /dev/null +++ b/app/src/main/res/layout/fragment_select_song.xml @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_song.xml b/app/src/main/res/layout/fragment_song.xml index 4f27235..b94be5a 100644 --- a/app/src/main/res/layout/fragment_song.xml +++ b/app/src/main/res/layout/fragment_song.xml @@ -58,7 +58,7 @@ app:layout_constraintBottom_toBottomOf="@id/songName" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="@id/songName" - app:srcCompat="@android:drawable/ic_menu_share" /> + app:srcCompat="@drawable/baseline_search_24" /> + app:startIconDrawable="@drawable/baseline_content_paste_24"> + + + + + + diff --git a/app/src/main/res/layout/song_search_item.xml b/app/src/main/res/layout/song_search_item.xml new file mode 100644 index 0000000..ae5bb09 --- /dev/null +++ b/app/src/main/res/layout/song_search_item.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml index 7eea45f..b5b21e9 100644 --- a/app/src/main/res/menu/bottom_nav_menu.xml +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -12,7 +12,7 @@ android:icon="@drawable/baseline_album_24"/> diff --git a/app/src/main/res/navigation/my_nav.xml b/app/src/main/res/navigation/my_nav.xml index 198b74f..917627e 100644 --- a/app/src/main/res/navigation/my_nav.xml +++ b/app/src/main/res/navigation/my_nav.xml @@ -36,10 +36,9 @@ android:name="com.example.spotifydownloader.Fragments.SongFragment" android:label="fragment_song" tools:layout="@layout/fragment_song" > - + app:argType="com.example.spotifydownloader.parcels.Data" /> + app:argType="com.example.spotifydownloader.parcels.DataSearch" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 947547e..c9be34d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,9 +8,9 @@ Progress bar Open Close - Save location + Choose Folder Download - Select save location + Select a folder to save the downloaded song @@ -26,12 +26,14 @@ - Song Name - Insert a Spotify song share link + Song name + Artist name (Not required) + Insert the song Name and artist Name Press Download to download the song Hello blank fragment Update Download Library + Select song to be downloaded \ No newline at end of file