Fix ringtone, file sharing
This commit is contained in:
parent
c9811ca06b
commit
fce012aaf3
20 changed files with 261 additions and 196 deletions
|
@ -32,6 +32,7 @@ import code.name.monkey.retromusic.ui.activities.tageditor.AbsTagEditorActivity
|
|||
import code.name.monkey.retromusic.ui.activities.tageditor.SongTagEditorActivity
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.RingtoneManager
|
||||
|
||||
|
||||
object SongMenuHelper {
|
||||
|
@ -40,7 +41,11 @@ object SongMenuHelper {
|
|||
fun handleMenuClick(activity: FragmentActivity, song: Song, menuItemId: Int): Boolean {
|
||||
when (menuItemId) {
|
||||
R.id.action_set_as_ringtone -> {
|
||||
MusicUtil.setRingtone(activity, song.id)
|
||||
if (RingtoneManager.requiresDialog(activity)) {
|
||||
RingtoneManager.getDialog(activity)
|
||||
}
|
||||
val ringtoneManager = RingtoneManager(activity)
|
||||
ringtoneManager.setRingtone(song)
|
||||
return true
|
||||
}
|
||||
R.id.action_share -> {
|
||||
|
|
|
@ -76,7 +76,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
|
|||
setupWindowTransition()
|
||||
super.onCreate(savedInstanceState)
|
||||
toggleBottomNavigationView(true)
|
||||
|
||||
collapsingToolbarLayout?.setBackgroundColor(ThemeStore.primaryColor(this))
|
||||
setLightNavigationBar(true)
|
||||
setNavigationbarColorAuto()
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
|||
|
||||
override fun onPageSelected(position: Int) {
|
||||
PreferenceUtil.getInstance().lyricsOptions = position
|
||||
if (position == 0) fab.text = "Sync lyrics"
|
||||
else if (position == 1) fab.text = "Lyrics"
|
||||
if (position == 0) fab.text = getString(R.string.synced_lyrics)
|
||||
else if (position == 1) fab.text = getString(R.string.lyrics)
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
|
@ -151,16 +151,23 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
|||
}
|
||||
|
||||
MaterialDialog(this).show {
|
||||
title(text = "Add lyrics")
|
||||
neutralButton(text = "Search") { RetroUtil.openUrl(this@LyricsActivity, googleSearchLrcUrl) }
|
||||
message(text = "Add time frame lyrics")
|
||||
negativeButton(text = "Delete") { LyricUtil.deleteLrcFile(song.title, song.artistName) }
|
||||
input(hint = "Paste lyrics here",
|
||||
title(R.string.add_time_framed_lryics)
|
||||
negativeButton(R.string.action_search) { RetroUtil.openUrl(this@LyricsActivity, googleSearchLrcUrl) }
|
||||
input(hint = getString(R.string.paste_lyrics_here),
|
||||
prefill = content,
|
||||
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) { _, input ->
|
||||
LyricUtil.writeLrcToLoc(song.title, song.artistName, input.toString())
|
||||
}
|
||||
positiveButton(android.R.string.ok)
|
||||
positiveButton(android.R.string.ok) {
|
||||
updateSong()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val page = supportFragmentManager.findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager.currentItem)
|
||||
if (viewPager.currentItem == 0 && page != null) {
|
||||
(page as BaseLyricsFragment).upDateSong()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,23 +179,24 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
|||
}
|
||||
|
||||
MaterialDialog(this).show {
|
||||
title(text = "Add lyrics")
|
||||
neutralButton(text = "Search") { RetroUtil.openUrl(this@LyricsActivity, getGoogleSearchUrl()) }
|
||||
negativeButton(text = "Delete") { LyricUtil.deleteLrcFile(song.title, song.artistName) }
|
||||
input(hint = "Paste lyrics here",
|
||||
title(R.string.add_lyrics)
|
||||
negativeButton(R.string.action_search) { RetroUtil.openUrl(this@LyricsActivity, getGoogleSearchUrl()) }
|
||||
input(hint = getString(R.string.paste_lyrics_here),
|
||||
prefill = content,
|
||||
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) { _, input ->
|
||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
|
||||
WriteTagsAsyncTask(this@LyricsActivity).execute(WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null))
|
||||
}
|
||||
positiveButton(android.R.string.ok)
|
||||
positiveButton(android.R.string.ok) {
|
||||
updateSong()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSongPaths(song: Song): ArrayList<String> {
|
||||
val paths = ArrayList<String>(1)
|
||||
paths.add(song.data!!)
|
||||
paths.add(song.data)
|
||||
return paths
|
||||
}
|
||||
|
||||
|
@ -318,9 +326,11 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
|||
|
||||
private fun setupLyricsView() {
|
||||
lyricsView.apply {
|
||||
val context = activity!!
|
||||
setCurrentPlayLineColor(ThemeStore.accentColor(context))
|
||||
setIndicatorTextColor(ThemeStore.accentColor(context))
|
||||
setCurrentIndicateLineTextColor(ThemeStore.textColorPrimary(context))
|
||||
setNoLrcTextColor(ThemeStore.textColorPrimary(context))
|
||||
setOnPlayIndicatorLineListener(object : LrcView.OnPlayIndicatorLineListener {
|
||||
override fun onPlay(time: Long, content: String) {
|
||||
MusicPlayerRemote.seekTo(time.toInt())
|
||||
|
|
|
@ -119,7 +119,11 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
|
|||
return true
|
||||
}
|
||||
R.id.action_set_as_ringtone -> {
|
||||
MusicUtil.setRingtone(activity!!, song.id)
|
||||
if (RingtoneManager.requiresDialog(activity!!)) {
|
||||
RingtoneManager.getDialog(activity!!)
|
||||
}
|
||||
val ringtoneManager = RingtoneManager(activity!!)
|
||||
ringtoneManager.setRingtone(song)
|
||||
return true
|
||||
}
|
||||
R.id.action_settings -> {
|
||||
|
|
|
@ -54,12 +54,6 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
|
|||
imageSettings.setOnClickListener(this)
|
||||
notificationSettings.setOnClickListener(this)
|
||||
otherSettings.setOnClickListener(this)
|
||||
|
||||
text.setTextColor(ThemeStore.textColorSecondary(context!!));
|
||||
titleWelcome.setTextColor(ThemeStore.textColorPrimary(context!!));
|
||||
titleWelcome.text = String.format("%s %s!", getTimeOfTheDay(), PreferenceUtil.getInstance().userName);
|
||||
loadImageFromStorage();
|
||||
userInfoContainer.setOnClickListener { NavigationUtil.goToUserInfo(activity!!) }
|
||||
}
|
||||
|
||||
private fun inflateFragment(fragment: Fragment, @StringRes title: Int) {
|
||||
|
@ -82,27 +76,4 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
|
|||
}
|
||||
return message
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private fun loadImageFromStorage() {
|
||||
|
||||
disposable.add(Compressor(context!!)
|
||||
.setMaxHeight(300)
|
||||
.setMaxWidth(300)
|
||||
.setQuality(75)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmapAsFlowable(
|
||||
File(PreferenceUtil.getInstance().profileImage, USER_PROFILE))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ userImage.setImageBitmap(it) }, {
|
||||
userImage.setImageDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_person_flat))
|
||||
}))
|
||||
}
|
||||
}
|
|
@ -25,11 +25,14 @@ import android.net.Uri;
|
|||
import android.os.Environment;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
|
@ -40,9 +43,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.FileProvider;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.loaders.PlaylistLoader;
|
||||
|
@ -72,9 +72,9 @@ public class MusicUtil {
|
|||
|
||||
@NonNull
|
||||
public static Intent createShareSongFileIntent(@NonNull final Song song, @NonNull Context context) {
|
||||
Uri file = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", new File(song.getData()));
|
||||
try {
|
||||
return new Intent().setAction(Intent.ACTION_SEND).putExtra(Intent.EXTRA_STREAM,
|
||||
FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName(), new File(song.getData())))
|
||||
return new Intent().setAction(Intent.ACTION_SEND).putExtra(Intent.EXTRA_STREAM, file)
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.setType("audio/*");
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
@ -84,41 +84,6 @@ public class MusicUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static void setRingtone(@NonNull final Context context, final int id) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Uri uri = getSongFileUri(id);
|
||||
try {
|
||||
final ContentValues values = new ContentValues(2);
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_RINGTONE, "1");
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_ALARM, "1");
|
||||
resolver.update(uri, values, null, null);
|
||||
} catch (@NonNull final UnsupportedOperationException ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
new String[]{MediaStore.MediaColumns.TITLE},
|
||||
BaseColumns._ID + "=?",
|
||||
new String[]{String.valueOf(id)},
|
||||
null);
|
||||
try {
|
||||
if (cursor != null && cursor.getCount() == 1) {
|
||||
cursor.moveToFirst();
|
||||
Settings.System.putString(resolver, Settings.System.RINGTONE, uri.toString());
|
||||
final String message = context
|
||||
.getString(R.string.x_has_been_set_as_ringtone, cursor.getString(0));
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
} catch (SecurityException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSongInfoString(@NonNull Song song) {
|
||||
return MusicUtil.buildInfoString(
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.util
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.provider.BaseColumns
|
||||
import android.provider.MediaStore
|
||||
import android.provider.Settings
|
||||
import android.widget.Toast
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil.getSongFileUri
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
|
||||
class RingtoneManager(val context: Context) {
|
||||
fun setRingtone(song: Song) {
|
||||
val resolver = context.contentResolver
|
||||
val uri = getSongFileUri(song.id)
|
||||
try {
|
||||
val values = ContentValues(2)
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_RINGTONE, "1")
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_ALARM, "1")
|
||||
resolver.update(uri, values, null, null)
|
||||
} catch (ignored: UnsupportedOperationException) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
val cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
arrayOf(MediaStore.MediaColumns.TITLE),
|
||||
BaseColumns._ID + "=?",
|
||||
arrayOf(song.id.toString()), null)
|
||||
cursor.use { cursorSong ->
|
||||
if (cursorSong != null && cursorSong.count == 1) {
|
||||
cursorSong.moveToFirst()
|
||||
Settings.System.putString(resolver, Settings.System.RINGTONE, uri.toString())
|
||||
val message = context
|
||||
.getString(R.string.x_has_been_set_as_ringtone, cursorSong.getString(0))
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
} catch (ignored: SecurityException) {
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "RingtoneManager"
|
||||
|
||||
fun requiresDialog(context: Context): Boolean {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (!Settings.System.canWrite(context)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getDialog(context: Context): MaterialDialog {
|
||||
return MaterialDialog(context).show {
|
||||
title(R.string.dialog_title_set_ringtone)
|
||||
message(R.string.dialog_message_set_ringtone)
|
||||
positiveButton(android.R.string.ok) {
|
||||
val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)
|
||||
intent.data = Uri.parse("package:" + context.applicationContext.packageName)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
negativeButton(android.R.string.cancel)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue