Removed remaining DocumentFile uses

Fixed lint issues
This commit is contained in:
Nite 2021-12-12 17:06:11 +01:00
parent fa4214a0ac
commit 66e7732ec2
No known key found for this signature in database
GPG Key ID: 1D1AD59B1C6386C1
31 changed files with 93 additions and 74 deletions

View File

@ -76,7 +76,7 @@ style:
UnnecessaryAbstractClass: UnnecessaryAbstractClass:
active: false active: false
ReturnCount: ReturnCount:
max: 3 max: 5
comments: comments:
active: true active: true

View File

@ -20,6 +20,7 @@ import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceCategory import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import java.io.File
import kotlin.math.ceil import kotlin.math.ceil
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.java.KoinJavaComponent.get import org.koin.java.KoinJavaComponent.get
@ -52,7 +53,6 @@ import org.moire.ultrasonic.util.TimeSpanPreferenceDialogFragmentCompat
import org.moire.ultrasonic.util.Util.toast import org.moire.ultrasonic.util.Util.toast
import org.moire.ultrasonic.util.isUri import org.moire.ultrasonic.util.isUri
import timber.log.Timber import timber.log.Timber
import java.io.File
/** /**
* Shows main app settings. * Shows main app settings.

View File

@ -3,11 +3,11 @@ package org.moire.ultrasonic.imageloader
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Build import android.os.Build
import java.io.File
import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.util.FileUtil import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
import timber.log.Timber import timber.log.Timber
import java.io.File
@Suppress("UtilityClassWithPublicConstructor") @Suppress("UtilityClassWithPublicConstructor")
class BitmapUtils { class BitmapUtils {

View File

@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat
import com.squareup.picasso.LruCache import com.squareup.picasso.LruCache
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import com.squareup.picasso.RequestCreator import com.squareup.picasso.RequestCreator
import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
@ -22,7 +23,6 @@ import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.util.FileUtil import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.Util.safeClose import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber import timber.log.Timber
import java.io.File
/** /**
* Our new image loader which uses Picasso as a backend. * Our new image loader which uses Picasso as a backend.

View File

@ -1,5 +1,6 @@
package org.moire.ultrasonic.log package org.moire.ultrasonic.log
import java.io.File
import java.io.FileWriter import java.io.FileWriter
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
@ -7,7 +8,6 @@ import java.util.Locale
import org.moire.ultrasonic.util.FileUtil import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.Util.safeClose import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber import timber.log.Timber
import java.io.File
/** /**
* A Timber Tree which can be used to log to a file * A Timber Tree which can be used to log to a file

View File

@ -22,9 +22,9 @@ import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
import org.moire.ultrasonic.subsonic.ImageLoaderProvider import org.moire.ultrasonic.subsonic.ImageLoaderProvider
import org.moire.ultrasonic.util.CacheCleaner import org.moire.ultrasonic.util.CacheCleaner
import org.moire.ultrasonic.util.CancellableTask import org.moire.ultrasonic.util.CancellableTask
import org.moire.ultrasonic.util.Storage
import org.moire.ultrasonic.util.FileUtil import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.Settings import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Storage
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
import org.moire.ultrasonic.util.Util.safeClose import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber import timber.log.Timber
@ -73,8 +73,10 @@ class DownloadFile(
init { init {
val state: DownloadStatus val state: DownloadStatus
partialFile = FileUtil.getParentPath(saveFile) + "/" + FileUtil.getPartialFile(FileUtil.getNameFromPath(saveFile)) partialFile = FileUtil.getParentPath(saveFile) + "/" +
completeFile = FileUtil.getParentPath(saveFile) + "/" + FileUtil.getCompleteFile(FileUtil.getNameFromPath(saveFile)) FileUtil.getPartialFile(FileUtil.getNameFromPath(saveFile))
completeFile = FileUtil.getParentPath(saveFile) + "/" +
FileUtil.getCompleteFile(FileUtil.getNameFromPath(saveFile))
when { when {
Storage.isPathExists(saveFile) -> { Storage.isPathExists(saveFile) -> {
@ -146,11 +148,11 @@ class DownloadFile(
@get:Synchronized @get:Synchronized
val isDownloading: Boolean val isDownloading: Boolean
get() = downloadPrepared || (downloadTask != null && downloadTask!!.isRunning) get() = downloadPrepared || (downloadTask != null && downloadTask!!.isRunning)
@get:Synchronized @get:Synchronized
val isDownloadCancelled: Boolean val isDownloadCancelled: Boolean
get() = downloadTask != null && downloadTask!!.isCancelled get() = downloadTask != null && downloadTask!!.isCancelled
fun shouldRetry(): Boolean { fun shouldRetry(): Boolean {
return (retryCount > 0) return (retryCount > 0)
@ -254,9 +256,8 @@ class DownloadFile(
val fileLength = Storage.getFromPath(partialFile)?.length ?: 0 val fileLength = Storage.getFromPath(partialFile)?.length ?: 0
needsDownloading = ( needsDownloading = (
desiredBitRate == 0 || duration == null || desiredBitRate == 0 || duration == null || duration == 0 || fileLength == 0L
duration == 0 || fileLength == 0L )
)
if (needsDownloading) { if (needsDownloading) {
// Attempt partial HTTP GET, appending to the file if it exists. // Attempt partial HTTP GET, appending to the file if it exists.
@ -270,7 +271,8 @@ class DownloadFile(
Timber.i("Executed partial HTTP GET, skipping %d bytes", fileLength) Timber.i("Executed partial HTTP GET, skipping %d bytes", fileLength)
} }
outputStream = Storage.getOrCreateFileFromPath(partialFile).getFileOutputStream(isPartial) outputStream = Storage.getOrCreateFileFromPath(partialFile)
.getFileOutputStream(isPartial)
val len = inputStream.copyTo(outputStream) { totalBytesCopied -> val len = inputStream.copyTo(outputStream) { totalBytesCopied ->
setProgress(totalBytesCopied) setProgress(totalBytesCopied)
@ -395,7 +397,7 @@ class DownloadFile(
} }
override val id: String override val id: String
get() = song.id get() = song.id
companion object { companion object {
const val MAX_RETRIES = 5 const val MAX_RETRIES = 5

View File

@ -187,7 +187,6 @@ class Downloader(
if (listChanged) { if (listChanged) {
updateLiveData() updateLiveData()
} }
} }
private fun updateLiveData() { private fun updateLiveData() {

View File

@ -19,7 +19,6 @@ import android.os.PowerManager
import android.os.PowerManager.PARTIAL_WAKE_LOCK import android.os.PowerManager.PARTIAL_WAKE_LOCK
import android.os.PowerManager.WakeLock import android.os.PowerManager.WakeLock
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import org.moire.ultrasonic.util.Storage
import java.net.URLEncoder import java.net.URLEncoder
import java.util.Locale import java.util.Locale
import kotlin.math.abs import kotlin.math.abs
@ -33,6 +32,7 @@ import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.util.CancellableTask import org.moire.ultrasonic.util.CancellableTask
import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.Settings import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Storage
import org.moire.ultrasonic.util.StreamProxy import org.moire.ultrasonic.util.StreamProxy
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
import timber.log.Timber import timber.log.Timber

View File

@ -9,7 +9,9 @@ package org.moire.ultrasonic.service
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import java.io.BufferedReader import java.io.BufferedReader
import java.io.BufferedWriter import java.io.BufferedWriter
import org.moire.ultrasonic.util.Storage import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.InputStream import java.io.InputStream
import java.io.Reader import java.io.Reader
import java.util.ArrayList import java.util.ArrayList
@ -40,11 +42,9 @@ import org.moire.ultrasonic.domain.UserInfo
import org.moire.ultrasonic.util.AbstractFile import org.moire.ultrasonic.util.AbstractFile
import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.FileUtil import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.Storage
import org.moire.ultrasonic.util.Util.safeClose import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber import timber.log.Timber
import java.io.File
import java.io.FileReader
import java.io.FileWriter
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
class OfflineMusicService : MusicService, KoinComponent { class OfflineMusicService : MusicService, KoinComponent {
@ -502,7 +502,6 @@ class OfflineMusicService : MusicService, KoinComponent {
return FileUtil.getBaseName(name) return FileUtil.getBaseName(name)
} }
private fun createEntry(file: AbstractFile, name: String?): MusicDirectory.Entry { private fun createEntry(file: AbstractFile, name: String?): MusicDirectory.Entry {
val entry = MusicDirectory.Entry(file.path) val entry = MusicDirectory.Entry(file.path)
entry.populateWithDataFrom(file, name) entry.populateWithDataFrom(file, name)

View File

@ -12,7 +12,7 @@ import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
abstract class AbstractFile: Comparable<AbstractFile> { abstract class AbstractFile : Comparable<AbstractFile> {
abstract val name: String abstract val name: String
abstract val isDirectory: Boolean abstract val isDirectory: Boolean
abstract val isFile: Boolean abstract val isFile: Boolean
@ -53,4 +53,4 @@ abstract class AbstractFile: Comparable<AbstractFile> {
} }
abstract fun rename(pathFrom: AbstractFile, pathTo: String) abstract fun rename(pathFrom: AbstractFile, pathTo: String)
} }

View File

@ -11,13 +11,13 @@ import org.koin.java.KoinJavaComponent.inject
import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.Playlist import org.moire.ultrasonic.domain.Playlist
import org.moire.ultrasonic.service.Downloader import org.moire.ultrasonic.service.Downloader
import org.moire.ultrasonic.util.FileUtil.delete
import org.moire.ultrasonic.util.FileUtil.getAlbumArtFile import org.moire.ultrasonic.util.FileUtil.getAlbumArtFile
import org.moire.ultrasonic.util.FileUtil.getPlaylistDirectory import org.moire.ultrasonic.util.FileUtil.getPlaylistDirectory
import org.moire.ultrasonic.util.FileUtil.getPlaylistFile import org.moire.ultrasonic.util.FileUtil.getPlaylistFile
import org.moire.ultrasonic.util.FileUtil.listFiles import org.moire.ultrasonic.util.FileUtil.listFiles
import org.moire.ultrasonic.util.FileUtil.musicDirectory import org.moire.ultrasonic.util.FileUtil.musicDirectory
import org.moire.ultrasonic.util.Settings.cacheSizeMB import org.moire.ultrasonic.util.Settings.cacheSizeMB
import org.moire.ultrasonic.util.FileUtil.delete
import org.moire.ultrasonic.util.Util.formatBytes import org.moire.ultrasonic.util.Util.formatBytes
import timber.log.Timber import timber.log.Timber

View File

@ -13,6 +13,7 @@ import android.os.Environment
import android.text.TextUtils import android.text.TextUtils
import android.util.Pair import android.util.Pair
import java.io.BufferedWriter import java.io.BufferedWriter
import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.FileWriter import java.io.FileWriter
@ -28,7 +29,6 @@ import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.util.Util.safeClose import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber import timber.log.Timber
import java.io.File
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
object FileUtil { object FileUtil {
@ -191,11 +191,11 @@ object FileUtil {
if (!TextUtils.isEmpty(entry.path) && getParentPath(entry.path!!) != null) { if (!TextUtils.isEmpty(entry.path) && getParentPath(entry.path!!) != null) {
val f = fileSystemSafeDir(entry.path) val f = fileSystemSafeDir(entry.path)
dir = String.format( dir = String.format(
Locale.ROOT, Locale.ROOT,
"%s/%s", "%s/%s",
musicDirectory.path, musicDirectory.path,
if (entry.isDirectory) f else getParentPath(f) ?: "" if (entry.isDirectory) f else getParentPath(f) ?: ""
) )
} else { } else {
val artist = fileSystemSafe(entry.artist) val artist = fileSystemSafe(entry.artist)
var album = fileSystemSafe(entry.album) var album = fileSystemSafe(entry.album)

View File

@ -9,14 +9,14 @@ package org.moire.ultrasonic.util
import android.content.res.AssetFileDescriptor import android.content.res.AssetFileDescriptor
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import org.moire.ultrasonic.app.UApp
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import org.moire.ultrasonic.app.UApp
class JavaFile(override val parent: AbstractFile?, val file: File): AbstractFile() { class JavaFile(override val parent: AbstractFile?, val file: File) : AbstractFile() {
override val name: String = file.name override val name: String = file.name
override val isDirectory: Boolean = file.isDirectory override val isDirectory: Boolean = file.isDirectory
override val isFile: Boolean = file.isFile override val isFile: Boolean = file.isFile
@ -33,7 +33,7 @@ class JavaFile(override val parent: AbstractFile?, val file: File): AbstractFile
override fun listFiles(): Array<AbstractFile> { override fun listFiles(): Array<AbstractFile> {
val fileList = file.listFiles() val fileList = file.listFiles()
return fileList?.map { file -> JavaFile(this, file) }?.toTypedArray() ?: emptyArray() return fileList?.map { file -> JavaFile(this, file) }?.toTypedArray() ?: emptyArray()
} }
override fun getFileOutputStream(append: Boolean): OutputStream { override fun getFileOutputStream(append: Boolean): OutputStream {

View File

@ -22,4 +22,4 @@ class ResettableLazy<T>(private val initializer: () -> T) {
fun reset() { fun reset() {
lazyRef.set(lazy(initializer)) lazyRef.set(lazy(initializer))
} }
} }

View File

@ -9,8 +9,8 @@ package org.moire.ultrasonic.util
import android.net.Uri import android.net.Uri
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import org.moire.ultrasonic.R
import java.io.File import java.io.File
import org.moire.ultrasonic.R
import org.moire.ultrasonic.app.UApp import org.moire.ultrasonic.app.UApp
import timber.log.Timber import timber.log.Timber
@ -21,7 +21,7 @@ import timber.log.Timber
object Storage { object Storage {
val mediaRoot: ResettableLazy<AbstractFile> = ResettableLazy { val mediaRoot: ResettableLazy<AbstractFile> = ResettableLazy {
getRoot()!! getRoot()!!
} }
private fun getRoot(): AbstractFile? { private fun getRoot(): AbstractFile? {

View File

@ -1,32 +1,54 @@
/*
* StorageFile.kt
* Copyright (C) 2009-2021 Ultrasonic developers
*
* Distributed under terms of the GNU GPLv3 license.
*/
package org.moire.ultrasonic.util package org.moire.ultrasonic.util
import android.content.res.AssetFileDescriptor import android.content.res.AssetFileDescriptor
import android.net.Uri import android.net.Uri
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import androidx.documentfile.provider.DocumentFile
import org.moire.ultrasonic.app.UApp
import timber.log.Timber
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import org.moire.ultrasonic.app.UApp
import timber.log.Timber
class StorageFile( class StorageFile(
override val parent: StorageFile?, override val parent: StorageFile?,
var uri: Uri, var uri: Uri,
override val name: String, override val name: String,
override val isDirectory: Boolean override val isDirectory: Boolean
): AbstractFile() { ) : AbstractFile() {
private val documentFile: DocumentFile = DocumentFile.fromSingleUri(UApp.applicationContext(), uri)!!
override val isFile: Boolean = !isDirectory override val isFile: Boolean = !isDirectory
override val length: Long override val length: Long
get() = documentFile.length() get() {
val resolver = UApp.applicationContext().contentResolver
val column = arrayOf(DocumentsContract.Document.COLUMN_SIZE)
resolver.query(uri, column, null, null, null)?.use { cursor ->
if (cursor.moveToFirst()) {
return cursor.getLong(0)
}
}
return 0
}
override val lastModified: Long override val lastModified: Long
get() = documentFile.lastModified() get() {
val resolver = UApp.applicationContext().contentResolver
val column = arrayOf(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
resolver.query(uri, column, null, null, null)?.use { cursor ->
if (cursor.moveToFirst()) {
return cursor.getLong(0)
}
}
return 0
}
override val path: String override val path: String
get() { get() {
@ -94,7 +116,6 @@ class StorageFile(
} }
override fun getFromPath(path: String): StorageFile? { override fun getFromPath(path: String): StorageFile? {
if (storageFilePathDictionary.containsKey(path)) if (storageFilePathDictionary.containsKey(path))
return storageFilePathDictionary[path]!! return storageFilePathDictionary[path]!!
if (notExistingPathDictionary.contains(path)) return null if (notExistingPathDictionary.contains(path)) return null
@ -108,7 +129,7 @@ class StorageFile(
val fileName = FileUtil.getNameFromPath(path) val fileName = FileUtil.getNameFromPath(path)
var file: StorageFile? = null var file: StorageFile? = null
Timber.v("StorageFile getFromPath path: $path") Timber.v("StorageFile getFromPath listing files on path: $path")
parent.listFiles().forEach { parent.listFiles().forEach {
if (it.name == fileName) file = it as StorageFile if (it.name == fileName) file = it as StorageFile
storageFilePathDictionary[it.path] = it as StorageFile storageFilePathDictionary[it.path] = it as StorageFile
@ -149,18 +170,28 @@ class StorageFile(
@Synchronized @Synchronized
override fun rename(pathFrom: AbstractFile, pathTo: String) { override fun rename(pathFrom: AbstractFile, pathTo: String) {
val storagePathFrom = pathFrom as StorageFile val fileFrom = pathFrom as StorageFile
if (!storagePathFrom.documentFile.exists()) throw IOException("File to rename doesn't exist") if (!fileFrom.exists()) throw IOException("File to rename doesn't exist")
Timber.d("Renaming from %s to %s", storagePathFrom.path, pathTo) Timber.d("Renaming from %s to %s", fileFrom.path, pathTo)
val parentTo = getFromPath(FileUtil.getParentPath(pathTo)!!) ?: throw IOException("Destination folder doesn't exist") val parentTo = getFromPath(FileUtil.getParentPath(pathTo)!!)
?: throw IOException("Destination folder doesn't exist")
val fileTo = getFromParentAndName(parentTo, FileUtil.getNameFromPath(pathTo)) val fileTo = getFromParentAndName(parentTo, FileUtil.getNameFromPath(pathTo))
copyFileContents(storagePathFrom.documentFile, fileTo.documentFile) copyFileContents(fileFrom, fileTo)
storagePathFrom.delete() fileFrom.delete()
notExistingPathDictionary.remove(pathTo) notExistingPathDictionary.remove(pathTo)
storageFilePathDictionary.remove(storagePathFrom.path) storageFilePathDictionary.remove(fileFrom.path)
}
private fun exists(): Boolean {
val resolver = UApp.applicationContext().contentResolver
val column = arrayOf(DocumentsContract.Document.COLUMN_DISPLAY_NAME)
resolver.query(uri, column, null, null, null)?.use { cursor ->
if (cursor.count != 0) return true
}
return false
} }
private fun getChildren(): List<StorageFile> { private fun getChildren(): List<StorageFile> {
@ -209,9 +240,9 @@ class StorageFile(
DocumentsContract.Document.COLUMN_MIME_TYPE DocumentsContract.Document.COLUMN_MIME_TYPE
) )
private fun copyFileContents(sourceFile: DocumentFile, destinationFile: DocumentFile) { private fun copyFileContents(sourceFile: AbstractFile, destinationFile: AbstractFile) {
UApp.applicationContext().contentResolver.openInputStream(sourceFile.uri)?.use { inputStream -> sourceFile.getFileInputStream().use { inputStream ->
UApp.applicationContext().contentResolver.openOutputStream(destinationFile.uri)?.use { outputStream -> destinationFile.getFileOutputStream(false).use { outputStream ->
inputStream.copyInto(outputStream) inputStream.copyInto(outputStream)
} }
} }
@ -238,9 +269,7 @@ class StorageFile(
return storageFilePathDictionary[parentPath]!! return storageFilePathDictionary[parentPath]!!
if (notExistingPathDictionary.contains(parentPath)) return null if (notExistingPathDictionary.contains(parentPath)) return null
val start = System.currentTimeMillis()
val parent = findStorageFileForParentDirectory(parentPath) val parent = findStorageFileForParentDirectory(parentPath)
val end = System.currentTimeMillis()
if (parent == null) { if (parent == null) {
storageFilePathDictionary.remove(parentPath) storageFilePathDictionary.remove(parentPath)
@ -253,6 +282,7 @@ class StorageFile(
return parent return parent
} }
@Suppress("NestedBlockDepth")
private fun findStorageFileForParentDirectory(path: String): StorageFile? { private fun findStorageFileForParentDirectory(path: String): StorageFile? {
val segments = getUriSegments(path) val segments = getUriSegments(path)
?: throw IOException("Can't get path because the root has changed") ?: throw IOException("Can't get path because the root has changed")

View File

@ -2,10 +2,10 @@ package org.moire.ultrasonic.util
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import java.io.File
import java.io.PrintWriter import java.io.PrintWriter
import org.moire.ultrasonic.util.Util.safeClose import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber import timber.log.Timber
import java.io.File
/** /**
* Logs the stack trace of uncaught exceptions to a file on the SD card. * Logs the stack trace of uncaught exceptions to a file on the SD card.

View File

@ -52,7 +52,6 @@ import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import kotlin.math.roundToInt import kotlin.math.roundToInt
import org.moire.ultrasonic.R import org.moire.ultrasonic.R
import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.app.UApp.Companion.applicationContext import org.moire.ultrasonic.app.UApp.Companion.applicationContext
import org.moire.ultrasonic.domain.Bookmark import org.moire.ultrasonic.domain.Bookmark
import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.domain.MusicDirectory
@ -757,7 +756,8 @@ object Util {
// TODO this doesn't work for URIs // TODO this doesn't work for URIs
MediaScannerConnection.scanFile( MediaScannerConnection.scanFile(
applicationContext(), arrayOf(file), applicationContext(), arrayOf(file),
null, null) null, null
)
} }
fun getResourceFromAttribute(context: Context, resId: Int): Int { fun getResourceFromAttribute(context: Context, resId: Int): Int {

View File

@ -16,6 +16,7 @@
a:layout_width="wrap_content" a:layout_width="wrap_content"
a:layout_height="wrap_content" a:layout_height="wrap_content"
a:layout_gravity="center_vertical" a:layout_gravity="center_vertical"
a:contentDescription="@null"
a:src="?attr/select_folder" /> a:src="?attr/select_folder" />
<LinearLayout <LinearLayout

View File

@ -348,7 +348,6 @@
<string name="share_default_greeting">Mrkni na hudbu sdílenou z %s</string> <string name="share_default_greeting">Mrkni na hudbu sdílenou z %s</string>
<string name="share_via">Sdílet skladby přes</string> <string name="share_via">Sdílet skladby přes</string>
<string name="menu.share">Sdílení</string> <string name="menu.share">Sdílení</string>
<string name="select_album_all_songs">Všechny skladby od %s</string>
<string name="settings.show_all_songs_by_artist">Zobrazit všechny skladby umělce</string> <string name="settings.show_all_songs_by_artist">Zobrazit všechny skladby umělce</string>
<string name="settings.show_all_songs_by_artist_summary">Přidat nový zápis v náhledu umělců pro přístup ke všem skladbám umělce</string> <string name="settings.show_all_songs_by_artist_summary">Přidat nový zápis v náhledu umělců pro přístup ke všem skladbám umělce</string>
<string name="download.menu_show_artist">Zobrazit umělce</string> <string name="download.menu_show_artist">Zobrazit umělce</string>

View File

@ -343,7 +343,6 @@
<string name="share_default_greeting">Hör dir mal die Musik an, die ich mit dir über %s geteilt habe.</string> <string name="share_default_greeting">Hör dir mal die Musik an, die ich mit dir über %s geteilt habe.</string>
<string name="share_via">Titel teilen über</string> <string name="share_via">Titel teilen über</string>
<string name="menu.share">Freigabe</string> <string name="menu.share">Freigabe</string>
<string name="select_album_all_songs">Alle Titel von %s</string>
<string name="settings.show_all_songs_by_artist">Alle Titel nach Künstler sortieren</string> <string name="settings.show_all_songs_by_artist">Alle Titel nach Künstler sortieren</string>
<string name="settings.show_all_songs_by_artist_summary">Einen neuen Eintrag in der Künstleransicht hinzufügen, um auf alle Lieder eines Künstlers zuzugreifen</string> <string name="settings.show_all_songs_by_artist_summary">Einen neuen Eintrag in der Künstleransicht hinzufügen, um auf alle Lieder eines Künstlers zuzugreifen</string>
<string name="download.menu_show_artist">Künstler zeigen</string> <string name="download.menu_show_artist">Künstler zeigen</string>

View File

@ -371,7 +371,6 @@
<string name="share_default_greeting">Echa un vistazo a esta música que te comparto desde %s</string> <string name="share_default_greeting">Echa un vistazo a esta música que te comparto desde %s</string>
<string name="share_via">Compartir canciones vía</string> <string name="share_via">Compartir canciones vía</string>
<string name="menu.share">Compartir</string> <string name="menu.share">Compartir</string>
<string name="select_album_all_songs">Todas las canciones por %s</string>
<string name="settings.show_all_songs_by_artist">Mostrar todas las canciones por artista</string> <string name="settings.show_all_songs_by_artist">Mostrar todas las canciones por artista</string>
<string name="settings.show_all_songs_by_artist_summary">Añadir nueva entrada en la vista de artista para acceder a todas las canciones de un artista</string> <string name="settings.show_all_songs_by_artist_summary">Añadir nueva entrada en la vista de artista para acceder a todas las canciones de un artista</string>
<string name="download.menu_show_artist">Mostrar artista</string> <string name="download.menu_show_artist">Mostrar artista</string>

View File

@ -362,7 +362,6 @@
<string name="share_default_greeting">Regardez cette musique que j\'ai partagée depuis %s</string> <string name="share_default_greeting">Regardez cette musique que j\'ai partagée depuis %s</string>
<string name="share_via">Partager des titres via</string> <string name="share_via">Partager des titres via</string>
<string name="menu.share">Partager</string> <string name="menu.share">Partager</string>
<string name="select_album_all_songs">Tous les titres de %s</string>
<string name="settings.show_all_songs_by_artist">Voir tous les titres par artiste</string> <string name="settings.show_all_songs_by_artist">Voir tous les titres par artiste</string>
<string name="settings.show_all_songs_by_artist_summary">Ajouter une nouvelle entrée dans la vue artiste pour accéder à toutes les titres d\'un artiste</string> <string name="settings.show_all_songs_by_artist_summary">Ajouter une nouvelle entrée dans la vue artiste pour accéder à toutes les titres d\'un artiste</string>
<string name="download.menu_show_artist">Afficher l\'artiste</string> <string name="download.menu_show_artist">Afficher l\'artiste</string>

View File

@ -360,7 +360,6 @@
<string name="share_default_greeting">Hallgasd meg ezt a zenét, megosztottam innen: %s</string> <string name="share_default_greeting">Hallgasd meg ezt a zenét, megosztottam innen: %s</string>
<string name="share_via">Dalok megosztása ezzel</string> <string name="share_via">Dalok megosztása ezzel</string>
<string name="menu.share">Megosztás</string> <string name="menu.share">Megosztás</string>
<string name="select_album_all_songs">%s minden dala</string>
<string name="settings.show_all_songs_by_artist">Az előadó összes dalának megjelenítése</string> <string name="settings.show_all_songs_by_artist">Az előadó összes dalának megjelenítése</string>
<string name="settings.show_all_songs_by_artist_summary">Új bejegyzés hozzáadása az előadóhoz, az előadó összes dalának eléréséhez.</string> <string name="settings.show_all_songs_by_artist_summary">Új bejegyzés hozzáadása az előadóhoz, az előadó összes dalának eléréséhez.</string>
<string name="download.menu_show_artist">Ugrás az előadóhoz</string> <string name="download.menu_show_artist">Ugrás az előadóhoz</string>

View File

@ -371,7 +371,6 @@
<string name="share_default_greeting">Hé, luister eens naar de muziek die ik heb gedeeld via %s</string> <string name="share_default_greeting">Hé, luister eens naar de muziek die ik heb gedeeld via %s</string>
<string name="share_via">Nummers delen via</string> <string name="share_via">Nummers delen via</string>
<string name="menu.share">Delen</string> <string name="menu.share">Delen</string>
<string name="select_album_all_songs">Alle nummers van %s</string>
<string name="settings.show_all_songs_by_artist">Alle nummers van artiest tonen</string> <string name="settings.show_all_songs_by_artist">Alle nummers van artiest tonen</string>
<string name="settings.show_all_songs_by_artist_summary">Item toevoegen in artiestweergave om alle nummers van een artiest te bekijken</string> <string name="settings.show_all_songs_by_artist_summary">Item toevoegen in artiestweergave om alle nummers van een artiest te bekijken</string>
<string name="download.menu_show_artist">Artiest tonen</string> <string name="download.menu_show_artist">Artiest tonen</string>

View File

@ -343,7 +343,6 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników
<string name="share_default_greeting">Sprawdź muzykę, którą udostępniam na %s</string> <string name="share_default_greeting">Sprawdź muzykę, którą udostępniam na %s</string>
<string name="share_via">Udostępnij utwory za pomocą</string> <string name="share_via">Udostępnij utwory za pomocą</string>
<string name="menu.share">Udostępnianie</string> <string name="menu.share">Udostępnianie</string>
<string name="select_album_all_songs">Wszystkie utwory %s</string>
<string name="settings.show_all_songs_by_artist">Wyświetlaj wszystkie utwory artysty</string> <string name="settings.show_all_songs_by_artist">Wyświetlaj wszystkie utwory artysty</string>
<string name="settings.show_all_songs_by_artist_summary">Dodaje nową pozycję w widoku artysty z wszystkimi jego utworami</string> <string name="settings.show_all_songs_by_artist_summary">Dodaje nową pozycję w widoku artysty z wszystkimi jego utworami</string>
<string name="download.menu_show_artist">Wyświetlaj artystę</string> <string name="download.menu_show_artist">Wyświetlaj artystę</string>

View File

@ -364,7 +364,6 @@
<string name="share_default_greeting">Confira esta música que compartilhei do %s</string> <string name="share_default_greeting">Confira esta música que compartilhei do %s</string>
<string name="share_via">Compartilhar músicas via</string> <string name="share_via">Compartilhar músicas via</string>
<string name="menu.share">Compartilhar</string> <string name="menu.share">Compartilhar</string>
<string name="select_album_all_songs">Todas as Músicas de %s</string>
<string name="settings.show_all_songs_by_artist">Mostrar Todas as Músicas por Artista</string> <string name="settings.show_all_songs_by_artist">Mostrar Todas as Músicas por Artista</string>
<string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para acessar todas as músicas do artista</string> <string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para acessar todas as músicas do artista</string>
<string name="download.menu_show_artist">Mostrar Artista</string> <string name="download.menu_show_artist">Mostrar Artista</string>

View File

@ -343,7 +343,6 @@
<string name="share_default_greeting">Confira esta música que compartilhei do %s</string> <string name="share_default_greeting">Confira esta música que compartilhei do %s</string>
<string name="share_via">Compartilhar músicas via</string> <string name="share_via">Compartilhar músicas via</string>
<string name="menu.share">Compartilhar</string> <string name="menu.share">Compartilhar</string>
<string name="select_album_all_songs">Todas as Músicas de %s</string>
<string name="settings.show_all_songs_by_artist">Todas as Músicas do Artista</string> <string name="settings.show_all_songs_by_artist">Todas as Músicas do Artista</string>
<string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para ver todas as músicas do artista</string> <string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para ver todas as músicas do artista</string>
<string name="download.menu_show_artist">Mostrar Artista</string> <string name="download.menu_show_artist">Mostrar Artista</string>

View File

@ -362,7 +362,6 @@
<string name="share_default_greeting">Проверьте эту музыку, с которой я поделился %s</string> <string name="share_default_greeting">Проверьте эту музыку, с которой я поделился %s</string>
<string name="share_via">Поделиться треками через</string> <string name="share_via">Поделиться треками через</string>
<string name="menu.share">Поделиться</string> <string name="menu.share">Поделиться</string>
<string name="select_album_all_songs">Все треки %s</string>
<string name="settings.show_all_songs_by_artist">Показать все треки исполнителя</string> <string name="settings.show_all_songs_by_artist">Показать все треки исполнителя</string>
<string name="settings.show_all_songs_by_artist_summary">Добавить новую запись в представлении исполнителя, чтобы получить доступ ко всем песням для исполнителя</string> <string name="settings.show_all_songs_by_artist_summary">Добавить новую запись в представлении исполнителя, чтобы получить доступ ко всем песням для исполнителя</string>
<string name="download.menu_show_artist">Показать исполнителей</string> <string name="download.menu_show_artist">Показать исполнителей</string>

View File

@ -360,7 +360,6 @@
<string name="share_default_greeting">看看我从 %s 分享的这首音乐</string> <string name="share_default_greeting">看看我从 %s 分享的这首音乐</string>
<string name="share_via">分享歌曲通过</string> <string name="share_via">分享歌曲通过</string>
<string name="menu.share">分享</string> <string name="menu.share">分享</string>
<string name="select_album_all_songs">%s 的所有歌曲</string>
<string name="settings.show_all_songs_by_artist">按艺术家显示所有歌曲</string> <string name="settings.show_all_songs_by_artist">按艺术家显示所有歌曲</string>
<string name="settings.show_all_songs_by_artist_summary">在艺术家视图中添加新条目以访问艺术家的所有歌曲</string> <string name="settings.show_all_songs_by_artist_summary">在艺术家视图中添加新条目以访问艺术家的所有歌曲</string>
<string name="download.menu_show_artist">显示艺术家</string> <string name="download.menu_show_artist">显示艺术家</string>

View File

@ -379,7 +379,6 @@
<string name="share_default_greeting">Check out this music I shared from %s</string> <string name="share_default_greeting">Check out this music I shared from %s</string>
<string name="share_via">Share songs via</string> <string name="share_via">Share songs via</string>
<string name="menu.share">Share</string> <string name="menu.share">Share</string>
<string name="select_album_all_songs">All Songs by %s</string>
<string name="settings.show_all_songs_by_artist">Show All Songs By Artist</string> <string name="settings.show_all_songs_by_artist">Show All Songs By Artist</string>
<string name="settings.show_all_songs_by_artist_summary">Add new entry in artist view to access all songs for an artist</string> <string name="settings.show_all_songs_by_artist_summary">Add new entry in artist view to access all songs for an artist</string>
<string name="download.menu_show_artist">Show Artist</string> <string name="download.menu_show_artist">Show Artist</string>