Fixed Playlist save

main
Prathamesh More 2021-11-17 16:52:39 +05:30
parent 9a32aa2805
commit e9b7b5a203
5 changed files with 129 additions and 33 deletions

View File

@ -21,13 +21,16 @@ import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.createNewFile
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.helper.M3UWriter
import code.name.monkey.retromusic.util.PlaylistsUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -46,22 +49,59 @@ class SavePlaylistDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch(Dispatchers.IO) {
val playlistWithSongs = extraNotNull<PlaylistWithSongs>(EXTRA_PLAYLIST).value
val file = PlaylistsUtil.savePlaylistWithSongs(playlistWithSongs)
MediaScannerConnection.scanFile(
requireActivity(),
arrayOf<String>(file.path),
null
) { _, _ ->
val playlistWithSongs = extraNotNull<PlaylistWithSongs>(EXTRA_PLAYLIST).value
if (VersionUtils.hasR()) {
createNewFile(
"audio/mpegurl",
playlistWithSongs.playlistEntity.playlistName
) { outputStream, data ->
try {
if (outputStream != null) {
lifecycleScope.launch(Dispatchers.IO) {
M3UWriter.writeIO(
outputStream,
playlistWithSongs
)
withContext(Dispatchers.Main) {
Toast.makeText(
requireContext(),
String.format(
requireContext().getString(R.string.saved_playlist_to),
data?.lastPathSegment
),
Toast.LENGTH_LONG
).show()
dismiss()
}
}
}
} catch (e: Exception) {
Toast.makeText(
context,
"Something went wrong : " + e.message,
Toast.LENGTH_SHORT
)
.show()
}
}
withContext(Dispatchers.Main) {
Toast.makeText(
requireContext(),
String.format(App.getContext().getString(R.string.saved_playlist_to), file),
Toast.LENGTH_LONG
).show()
dismiss()
} else {
lifecycleScope.launch(Dispatchers.IO) {
val file = PlaylistsUtil.savePlaylistWithSongs(playlistWithSongs)
MediaScannerConnection.scanFile(
requireActivity(),
arrayOf<String>(file.path),
null
) { _, _ ->
}
withContext(Dispatchers.Main) {
Toast.makeText(
requireContext(),
String.format(App.getContext().getString(R.string.saved_playlist_to), file),
Toast.LENGTH_LONG
).show()
dismiss()
}
}
}
}

View File

@ -0,0 +1,35 @@
package code.name.monkey.retromusic.extensions
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Environment
import android.provider.DocumentsContract
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment
import java.io.File
import java.io.OutputStream
fun Fragment.createNewFile(
mimeType: String,
fileName: String,
write: (outputStream: OutputStream?, data: Uri?) -> Unit
) {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = mimeType
intent.putExtra(Intent.EXTRA_TITLE, fileName)
val startForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult())
{ result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
val outputStream: OutputStream? =
context?.contentResolver?.openOutputStream(result.data?.data!!)
write(outputStream, result.data?.data)
}
}
startForResult.launch(intent)
}

View File

@ -18,10 +18,7 @@ import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.io.*
object M3UWriter : M3UConstants {
@JvmStatic
@ -69,4 +66,23 @@ object M3UWriter : M3UConstants {
}
return file
}
fun writeIO(outputStream: OutputStream, playlistWithSongs: PlaylistWithSongs) {
val songs: List<Song> = playlistWithSongs.songs.sortedBy {
it.songPrimaryKey
}.toSongs()
if (songs.isNotEmpty()) {
val bufferedWriter = outputStream.bufferedWriter()
bufferedWriter.write(M3UConstants.HEADER)
songs.forEach {
bufferedWriter.newLine()
bufferedWriter.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title)
bufferedWriter.newLine()
bufferedWriter.write(it.data)
}
bufferedWriter.close()
}
outputStream.flush()
outputStream.close()
}
}

View File

@ -36,6 +36,7 @@ import java.util.List;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.db.PlaylistWithSongs;
import code.name.monkey.retromusic.helper.M3UConstants;
import code.name.monkey.retromusic.helper.M3UWriter;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.PlaylistSong;
@ -319,9 +320,9 @@ public class PlaylistsUtil {
private static boolean doesPlaylistExist(
@NonNull Context context, @NonNull final String selection, @NonNull final String[] values) {
Cursor cursor =
context
.getContentResolver()
.query(EXTERNAL_CONTENT_URI, new String[] {}, selection, values, null);
context
.getContentResolver()
.query(EXTERNAL_CONTENT_URI, new String[]{}, selection, values, null);
boolean exists = false;
if (cursor != null) {

View File

@ -8,18 +8,11 @@ import android.os.Build
object VersionUtils {
/**
* @return true if device is running API >= 21
*/
fun hasLollipop(): Boolean {
return Build.VERSION.SDK_INT >= 21
}
/**
* @return true if device is running API >= 23
*/
fun hasMarshmallow(): Boolean {
return Build.VERSION.SDK_INT >= 23
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
}
/**
@ -30,7 +23,7 @@ object VersionUtils {
}
/**
* @return true if device is running API >= 24
* @return true if device is running API >= 25
*/
fun hasNougatMR(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1
@ -44,20 +37,31 @@ object VersionUtils {
}
/**
* @return true if device is running API >= 27
* @return true if device is running API >= 28
*/
fun hasP(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
}
/**
* @return true if device is running API >= 28
* @return true if device is running API >= 29
*/
@JvmStatic
fun hasQ(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
}
/**
* @return true if device is running API >= 30
*/
@JvmStatic
fun hasR(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
}
/**
* @return true if device is running API >= 31
*/
@JvmStatic
fun hasS(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S