1
0
mirror of https://github.com/ultrasonic/ultrasonic synced 2025-03-12 09:30:14 +01:00

Merge pull request #559 from Maxmystere/Improve-Offline-Support

Add better offline Support
This commit is contained in:
tzugen 2021-08-27 12:08:14 +02:00 committed by GitHub
commit 029f0fa4da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 318 additions and 286 deletions

View File

@ -15,7 +15,12 @@ data class Share(
private val entries: MutableList<Entry> = mutableListOf()
) : Serializable, GenericEntry() {
override val name: String?
get() = url?.let { urlPattern.matcher(url).replaceFirst("$1") }
get() {
if (url != null) {
return urlPattern.matcher(url!!).replaceFirst("$1")
}
return null
}
fun getEntries(): List<Entry> {
return entries.toList()

View File

@ -30,7 +30,6 @@
<ID>LongMethod:EditServerFragment.kt$EditServerFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
<ID>LongMethod:FilePickerAdapter.kt$FilePickerAdapter$private fun fileLister(currentDirectory: File)</ID>
<ID>LongMethod:LocalMediaPlayer.kt$LocalMediaPlayer$@Synchronized private fun doPlay(downloadFile: DownloadFile, position: Int, start: Boolean)</ID>
<ID>LongMethod:MediaPlayerService.kt$MediaPlayerService$private fun updateMediaSession(currentPlaying: DownloadFile?, playerState: PlayerState)</ID>
<ID>LongMethod:NavigationActivity.kt$NavigationActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
<ID>LongMethod:ShareHandler.kt$ShareHandler$private fun showDialog( fragment: Fragment, shareDetails: ShareDetails, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken )</ID>
<ID>LongMethod:SongView.kt$SongView$fun setSong(song: MusicDirectory.Entry, checkable: Boolean, draggable: Boolean)</ID>
@ -49,7 +48,6 @@
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.BufferTask$86400L</ID>
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.BufferTask$8L</ID>
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.CheckCompletionTask$5000L</ID>
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$50L</ID>
<ID>MagicNumber:MediaPlayerService.kt$MediaPlayerService$256</ID>
<ID>MagicNumber:MediaPlayerService.kt$MediaPlayerService$3</ID>
<ID>MagicNumber:MediaPlayerService.kt$MediaPlayerService$4</ID>
@ -70,11 +68,9 @@
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer$exception: Throwable</ID>
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer$x: Exception</ID>
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$e: Exception</ID>
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$e: Exception</ID>
<ID>TooGenericExceptionCaught:SongView.kt$SongView$e: Exception</ID>
<ID>TooGenericExceptionCaught:SubsonicUncaughtExceptionHandler.kt$SubsonicUncaughtExceptionHandler$x: Throwable</ID>
<ID>TooGenericExceptionThrown:DownloadFile.kt$DownloadFile.DownloadTask$throw Exception(String.format("Download of '%s' was cancelled", song))</ID>
<ID>TooManyFunctions:LocalMediaPlayer.kt$LocalMediaPlayer</ID>
<ID>TooManyFunctions:MediaPlayerService.kt$MediaPlayerService : Service</ID>
<ID>TooManyFunctions:RESTMusicService.kt$RESTMusicService : MusicService</ID>
<ID>TooManyFunctions:TrackCollectionFragment.kt$TrackCollectionFragment : Fragment</ID>

View File

@ -1,265 +0,0 @@
package org.moire.ultrasonic.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;
import org.moire.ultrasonic.R;
import org.moire.ultrasonic.data.ActiveServerProvider;
import org.moire.ultrasonic.data.ServerSetting;
import org.moire.ultrasonic.util.Constants;
import org.moire.ultrasonic.util.MergeAdapter;
import org.moire.ultrasonic.util.Util;
import java.util.Collections;
import kotlin.Lazy;
import static java.util.Arrays.asList;
import static org.koin.java.KoinJavaComponent.inject;
/**
* Displays the Main screen of Ultrasonic, where the music library can be browsed
*/
public class MainFragment extends Fragment {
private static boolean shouldUseId3;
private static String lastActiveServerProperties;
private ListView list;
private final Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Util.applyTheme(this.getContext());
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.main, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
list = view.findViewById(R.id.main_list);
setupMenuList(list);
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
boolean shouldRestart = false;
boolean id3 = Util.getShouldUseId3Tags();
String currentActiveServerProperties = getActiveServerProperties();
if (id3 != shouldUseId3)
{
shouldUseId3 = id3;
shouldRestart = true;
}
if (!currentActiveServerProperties.equals(lastActiveServerProperties))
{
lastActiveServerProperties = currentActiveServerProperties;
shouldRestart = true;
}
if (shouldRestart) {
setupMenuList(list);
}
}
private void setupMenuList(ListView list)
{
final View buttons = getLayoutInflater().inflate(R.layout.main_buttons, list, false);
final View serverButton = buttons.findViewById(R.id.main_select_server);
final TextView serverTextView = serverButton.findViewById(R.id.main_select_server_2);
lastActiveServerProperties = getActiveServerProperties();
String name = activeServerProvider.getValue().getActiveServer().getName();
serverTextView.setText(name);
final View musicTitle = buttons.findViewById(R.id.main_music);
final View artistsButton = buttons.findViewById(R.id.main_artists_button);
final View albumsButton = buttons.findViewById(R.id.main_albums_button);
final View genresButton = buttons.findViewById(R.id.main_genres_button);
final View videosTitle = buttons.findViewById(R.id.main_videos_title);
final View songsTitle = buttons.findViewById(R.id.main_songs);
final View randomSongsButton = buttons.findViewById(R.id.main_songs_button);
final View songsStarredButton = buttons.findViewById(R.id.main_songs_starred);
final View albumsTitle = buttons.findViewById(R.id.main_albums);
final View albumsNewestButton = buttons.findViewById(R.id.main_albums_newest);
final View albumsRandomButton = buttons.findViewById(R.id.main_albums_random);
final View albumsHighestButton = buttons.findViewById(R.id.main_albums_highest);
final View albumsStarredButton = buttons.findViewById(R.id.main_albums_starred);
final View albumsRecentButton = buttons.findViewById(R.id.main_albums_recent);
final View albumsFrequentButton = buttons.findViewById(R.id.main_albums_frequent);
final View albumsAlphaByNameButton = buttons.findViewById(R.id.main_albums_alphaByName);
final View albumsAlphaByArtistButton = buttons.findViewById(R.id.main_albums_alphaByArtist);
final View videosButton = buttons.findViewById(R.id.main_videos);
final MergeAdapter adapter = new MergeAdapter();
adapter.addViews(Collections.singletonList(serverButton), true);
if (!ActiveServerProvider.Companion.isOffline())
{
adapter.addView(musicTitle, false);
adapter.addViews(asList(artistsButton, albumsButton, genresButton), true);
adapter.addView(songsTitle, false);
adapter.addViews(asList(randomSongsButton, songsStarredButton), true);
adapter.addView(albumsTitle, false);
if (Util.getShouldUseId3Tags())
{
shouldUseId3 = true;
adapter.addViews(asList(albumsNewestButton, albumsRecentButton, albumsFrequentButton, albumsRandomButton, albumsStarredButton, albumsAlphaByNameButton, albumsAlphaByArtistButton), true);
}
else
{
shouldUseId3 = false;
adapter.addViews(asList(albumsNewestButton, albumsRecentButton, albumsFrequentButton, albumsHighestButton, albumsRandomButton, albumsStarredButton, albumsAlphaByNameButton, albumsAlphaByArtistButton), true);
}
adapter.addView(videosTitle, false);
adapter.addViews(Collections.singletonList(videosButton), true);
}
list.setAdapter(adapter);
list.setOnItemClickListener((parent, view, position, id) -> {
if (view == serverButton)
{
showServers();
}
else if (view == albumsNewestButton)
{
showAlbumList("newest", R.string.main_albums_newest);
}
else if (view == albumsRandomButton)
{
showAlbumList("random", R.string.main_albums_random);
}
else if (view == albumsHighestButton)
{
showAlbumList("highest", R.string.main_albums_highest);
}
else if (view == albumsRecentButton)
{
showAlbumList("recent", R.string.main_albums_recent);
}
else if (view == albumsFrequentButton)
{
showAlbumList("frequent", R.string.main_albums_frequent);
}
else if (view == albumsStarredButton)
{
showAlbumList(Constants.STARRED, R.string.main_albums_starred);
}
else if (view == albumsAlphaByNameButton)
{
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_alphaByName);
}
else if (view == albumsAlphaByArtistButton)
{
showAlbumList("alphabeticalByArtist", R.string.main_albums_alphaByArtist);
}
else if (view == songsStarredButton)
{
showStarredSongs();
}
else if (view == artistsButton)
{
showArtists();
}
else if (view == albumsButton)
{
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_title);
}
else if (view == randomSongsButton)
{
showRandomSongs();
}
else if (view == genresButton)
{
showGenres();
}
else if (view == videosButton)
{
showVideos();
}
});
}
private String getActiveServerProperties()
{
ServerSetting currentSetting = activeServerProvider.getValue().getActiveServer();
return String.format("%s;%s;%s;%s;%s;%s", currentSetting.getUrl(), currentSetting.getUserName(),
currentSetting.getPassword(), currentSetting.getAllowSelfSignedCertificate(),
currentSetting.getLdapSupport(), currentSetting.getMinimumApiVersion());
}
private void showStarredSongs()
{
Bundle bundle = new Bundle();
bundle.putInt(Constants.INTENT_EXTRA_NAME_STARRED, 1);
Navigation.findNavController(getView()).navigate(R.id.mainToTrackCollection, bundle);
}
private void showRandomSongs()
{
Bundle bundle = new Bundle();
bundle.putInt(Constants.INTENT_EXTRA_NAME_RANDOM, 1);
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, Util.getMaxSongs());
Navigation.findNavController(getView()).navigate(R.id.mainToTrackCollection, bundle);
}
private void showArtists()
{
Bundle bundle = new Bundle();
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, getContext().getResources().getString(R.string.main_artists_title));
Navigation.findNavController(getView()).navigate(R.id.mainToArtistList, bundle);
}
private void showAlbumList(final String type, final int titleIndex) {
Bundle bundle = new Bundle();
String title = getContext().getResources().getString(titleIndex, "");
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type);
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, title);
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, Util.getMaxAlbums());
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0);
Navigation.findNavController(getView()).navigate(R.id.mainToAlbumList, bundle);
}
private void showGenres()
{
Navigation.findNavController(getView()).navigate(R.id.mainToSelectGenre);
}
private void showVideos()
{
Bundle bundle = new Bundle();
bundle.putInt(Constants.INTENT_EXTRA_NAME_VIDEOS, 1);
Navigation.findNavController(getView()).navigate(R.id.mainToTrackCollection, bundle);
}
private void showServers()
{
Navigation.findNavController(getView()).navigate(R.id.mainToServerSelector);
}
}

View File

@ -0,0 +1,294 @@
package org.moire.ultrasonic.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import java.util.Locale
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.MergeAdapter
import org.moire.ultrasonic.util.Util.applyTheme
import org.moire.ultrasonic.util.Util.getMaxAlbums
import org.moire.ultrasonic.util.Util.getMaxSongs
import org.moire.ultrasonic.util.Util.getShouldUseId3Tags
/**
* Displays the Main screen of Ultrasonic, where the music library can be browsed
*/
class MainFragment : Fragment(), KoinComponent {
private var list: ListView? = null
private lateinit var serverButton: View
private lateinit var serverTextView: TextView
private lateinit var musicTitle: View
private lateinit var artistsButton: View
private lateinit var albumsButton: View
private lateinit var genresButton: View
private lateinit var videosTitle: View
private lateinit var songsTitle: View
private lateinit var randomSongsButton: View
private lateinit var songsStarredButton: View
private lateinit var albumsTitle: View
private lateinit var albumsNewestButton: View
private lateinit var albumsRandomButton: View
private lateinit var albumsHighestButton: View
private lateinit var albumsStarredButton: View
private lateinit var albumsRecentButton: View
private lateinit var albumsFrequentButton: View
private lateinit var albumsAlphaByNameButton: View
private lateinit var albumsAlphaByArtistButton: View
private lateinit var videosButton: View
private val activeServerProvider: ActiveServerProvider by inject()
override fun onCreate(savedInstanceState: Bundle?) {
applyTheme(this.context)
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.main, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
list = view.findViewById(R.id.main_list)
cachedActiveServerProperties = getActiveServerProperties()
setupButtons()
if (list != null) setupMenuList(list!!)
super.onViewCreated(view, savedInstanceState)
}
override fun onResume() {
super.onResume()
var shouldRestart = false
val currentId3Setting = getShouldUseId3Tags()
val currentActiveServerProperties = getActiveServerProperties()
// If setting has changed...
if (currentId3Setting != shouldUseId3) {
shouldUseId3 = currentId3Setting
shouldRestart = true
}
// or the server has changed...
if (currentActiveServerProperties != cachedActiveServerProperties) {
cachedActiveServerProperties = currentActiveServerProperties
shouldRestart = true
}
// then setup the list anew.
if (shouldRestart) {
if (list != null) setupMenuList(list!!)
}
}
private fun setupButtons() {
val buttons = layoutInflater.inflate(R.layout.main_buttons, list, false)
serverButton = buttons.findViewById(R.id.main_select_server)
serverTextView = serverButton.findViewById(R.id.main_select_server_2)
musicTitle = buttons.findViewById(R.id.main_music)
artistsButton = buttons.findViewById(R.id.main_artists_button)
albumsButton = buttons.findViewById(R.id.main_albums_button)
genresButton = buttons.findViewById(R.id.main_genres_button)
videosTitle = buttons.findViewById(R.id.main_videos_title)
songsTitle = buttons.findViewById(R.id.main_songs)
randomSongsButton = buttons.findViewById(R.id.main_songs_button)
songsStarredButton = buttons.findViewById(R.id.main_songs_starred)
albumsTitle = buttons.findViewById(R.id.main_albums)
albumsNewestButton = buttons.findViewById(R.id.main_albums_newest)
albumsRandomButton = buttons.findViewById(R.id.main_albums_random)
albumsHighestButton = buttons.findViewById(R.id.main_albums_highest)
albumsStarredButton = buttons.findViewById(R.id.main_albums_starred)
albumsRecentButton = buttons.findViewById(R.id.main_albums_recent)
albumsFrequentButton = buttons.findViewById(R.id.main_albums_frequent)
albumsAlphaByNameButton = buttons.findViewById(R.id.main_albums_alphaByName)
albumsAlphaByArtistButton = buttons.findViewById(R.id.main_albums_alphaByArtist)
videosButton = buttons.findViewById(R.id.main_videos)
}
private fun setupMenuList(list: ListView) {
// Set title
val activeServerName = activeServerProvider.getActiveServer().name
serverTextView.text = activeServerName
// TODO: Should use RecyclerView
val adapter = MergeAdapter()
adapter.addView(serverButton, true)
shouldUseId3 = getShouldUseId3Tags()
if (!isOffline()) {
adapter.addView(musicTitle, false)
adapter.addViews(listOf(artistsButton, albumsButton, genresButton), true)
adapter.addView(songsTitle, false)
adapter.addViews(listOf(randomSongsButton, songsStarredButton), true)
adapter.addView(albumsTitle, false)
adapter.addViews(
listOf(
albumsNewestButton,
albumsRecentButton,
albumsFrequentButton
),
true
)
if (!shouldUseId3) {
adapter.addView(albumsHighestButton, true)
}
adapter.addViews(
listOf(
albumsRandomButton,
albumsStarredButton,
albumsAlphaByNameButton,
albumsAlphaByArtistButton
),
true
)
adapter.addView(videosTitle, false)
adapter.addViews(listOf(videosButton), true)
} else {
// Offline supported calls
adapter.addView(musicTitle, false)
adapter.addViews(listOf(artistsButton, genresButton), true)
adapter.addView(songsTitle, false)
adapter.addView(randomSongsButton, true)
}
list.adapter = adapter
list.onItemClickListener = listListener
}
private val listListener =
OnItemClickListener { _: AdapterView<*>?, view: View, _: Int, _: Long ->
when {
view === serverButton -> {
showServers()
}
view === albumsNewestButton -> {
showAlbumList("newest", R.string.main_albums_newest)
}
view === albumsRandomButton -> {
showAlbumList("random", R.string.main_albums_random)
}
view === albumsHighestButton -> {
showAlbumList("highest", R.string.main_albums_highest)
}
view === albumsRecentButton -> {
showAlbumList("recent", R.string.main_albums_recent)
}
view === albumsFrequentButton -> {
showAlbumList("frequent", R.string.main_albums_frequent)
}
view === albumsStarredButton -> {
showAlbumList(Constants.STARRED, R.string.main_albums_starred)
}
view === albumsAlphaByNameButton -> {
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_alphaByName)
}
view === albumsAlphaByArtistButton -> {
showAlbumList("alphabeticalByArtist", R.string.main_albums_alphaByArtist)
}
view === songsStarredButton -> {
showStarredSongs()
}
view === artistsButton -> {
showArtists()
}
view === albumsButton -> {
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_title)
}
view === randomSongsButton -> {
showRandomSongs()
}
view === genresButton -> {
showGenres()
}
view === videosButton -> {
showVideos()
}
}
}
private fun getActiveServerProperties(): String {
val server = activeServerProvider.getActiveServer()
return String.format(
Locale.ROOT,
"%s;%s;%s;%s;%s;%s",
server.url,
server.userName,
server.password,
server.allowSelfSignedCertificate,
server.ldapSupport,
server.minimumApiVersion
)
}
private fun showStarredSongs() {
val bundle = Bundle()
bundle.putInt(Constants.INTENT_EXTRA_NAME_STARRED, 1)
Navigation.findNavController(requireView()).navigate(R.id.mainToTrackCollection, bundle)
}
private fun showRandomSongs() {
val bundle = Bundle()
bundle.putInt(Constants.INTENT_EXTRA_NAME_RANDOM, 1)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, getMaxSongs())
Navigation.findNavController(requireView()).navigate(R.id.mainToTrackCollection, bundle)
}
private fun showArtists() {
val bundle = Bundle()
bundle.putString(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE,
requireContext().resources.getString(R.string.main_artists_title)
)
Navigation.findNavController(requireView()).navigate(R.id.mainToArtistList, bundle)
}
private fun showAlbumList(type: String, titleIndex: Int) {
val bundle = Bundle()
val title = requireContext().resources.getString(titleIndex, "")
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type)
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, title)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, getMaxAlbums())
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0)
Navigation.findNavController(requireView()).navigate(R.id.mainToAlbumList, bundle)
}
private fun showGenres() {
Navigation.findNavController(requireView()).navigate(R.id.mainToSelectGenre)
}
private fun showVideos() {
val bundle = Bundle()
bundle.putInt(Constants.INTENT_EXTRA_NAME_VIDEOS, 1)
Navigation.findNavController(requireView()).navigate(R.id.mainToTrackCollection, bundle)
}
private fun showServers() {
Navigation.findNavController(requireView()).navigate(R.id.mainToServerSelector)
}
companion object {
private var shouldUseId3 = false
private var cachedActiveServerProperties: String? = null
}
}

View File

@ -14,11 +14,11 @@ import java.io.FileReader
import java.io.FileWriter
import java.io.InputStream
import java.io.Reader
import java.lang.Math.min
import java.util.ArrayList
import java.util.HashSet
import java.util.LinkedList
import java.util.Locale
import java.util.Random
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern
import org.koin.core.component.KoinComponent
@ -257,9 +257,10 @@ class OfflineMusicService : MusicService, KoinComponent {
if (children.isEmpty()) {
return result
}
val random = Random()
for (i in 0 until size) {
val file = children[random.nextInt(children.size)]
children.shuffle()
val finalSize: Int = min(children.size, size)
for (i in 0 until finalSize) {
val file = children[i % children.size]
result.addChild(createEntry(file, getName(file)))
}
return result

View File

@ -87,10 +87,10 @@ object Util {
private var MEGA_BYTE_LOCALIZED_FORMAT: DecimalFormat? = null
private var KILO_BYTE_LOCALIZED_FORMAT: DecimalFormat? = null
private var BYTE_LOCALIZED_FORMAT: DecimalFormat? = null
const val EVENT_META_CHANGED = "org.moire.ultrasonic.EVENT_META_CHANGED"
const val EVENT_PLAYSTATE_CHANGED = "org.moire.ultrasonic.EVENT_PLAYSTATE_CHANGED"
const val CM_AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged"
const val CM_AVRCP_METADATA_CHANGED = "com.android.music.metachanged"
private const val EVENT_META_CHANGED = "org.moire.ultrasonic.EVENT_META_CHANGED"
private const val EVENT_PLAYSTATE_CHANGED = "org.moire.ultrasonic.EVENT_PLAYSTATE_CHANGED"
private const val CM_AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged"
private const val CM_AVRCP_METADATA_CHANGED = "com.android.music.metachanged"
// Used by hexEncode()
private val HEX_DIGITS =
@ -440,6 +440,7 @@ object Util {
return BYTE_LOCALIZED_FORMAT!!.format(byteCount.toDouble())
}
@Suppress("SuspiciousEqualsCombination")
fun equals(object1: Any?, object2: Any?): Boolean {
return object1 === object2 || !(object1 == null || object2 == null) && object1 == object2
}
@ -624,10 +625,10 @@ object Util {
// Assume the size given refers to the width of the image, so calculate the new height using
// the previously determined aspect ratio
return Math.round(newWidth * aspectRatio).toInt()
return (newWidth * aspectRatio).roundToInt()
}
fun getScaledHeight(bitmap: Bitmap, width: Int): Int {
private fun getScaledHeight(bitmap: Bitmap, width: Int): Int {
return getScaledHeight(bitmap.height.toDouble(), bitmap.width.toDouble(), width)
}
@ -851,12 +852,12 @@ object Util {
fun getMinDisplayMetric(): Int {
val metrics = appContext().resources.displayMetrics
return Math.min(metrics.widthPixels, metrics.heightPixels)
return min(metrics.widthPixels, metrics.heightPixels)
}
fun getMaxDisplayMetric(): Int {
val metrics = appContext().resources.displayMetrics
return Math.max(metrics.widthPixels, metrics.heightPixels)
return max(metrics.widthPixels, metrics.heightPixels)
}
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
@ -868,14 +869,14 @@ object Util {
// Calculate ratios of height and width to requested height and
// width
val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
val heightRatio = (height.toFloat() / reqHeight.toFloat()).roundToInt()
val widthRatio = (width.toFloat() / reqWidth.toFloat()).roundToInt()
// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = Math.min(heightRatio, widthRatio)
inSampleSize = min(heightRatio, widthRatio)
}
return inSampleSize
}
@ -1091,7 +1092,7 @@ object Util {
)
}
fun getShouldSendBluetoothAlbumArt(): Boolean {
private fun getShouldSendBluetoothAlbumArt(): Boolean {
val preferences = getPreferences()
return preferences.getBoolean(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_ALBUM_ART, true)
}