mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-26 05:32:15 +03:00
Implemented file logging settings
Implemented log rotation, log deletion Minor fixes
This commit is contained in:
parent
5de20861ca
commit
6e7ebeabef
@ -22,6 +22,7 @@ import org.moire.ultrasonic.featureflags.Feature;
|
|||||||
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
||||||
import org.moire.ultrasonic.filepicker.FilePickerDialog;
|
import org.moire.ultrasonic.filepicker.FilePickerDialog;
|
||||||
import org.moire.ultrasonic.filepicker.OnFileSelectedListener;
|
import org.moire.ultrasonic.filepicker.OnFileSelectedListener;
|
||||||
|
import org.moire.ultrasonic.log.FileLoggerTree;
|
||||||
import org.moire.ultrasonic.provider.SearchSuggestionProvider;
|
import org.moire.ultrasonic.provider.SearchSuggestionProvider;
|
||||||
import org.moire.ultrasonic.service.Consumer;
|
import org.moire.ultrasonic.service.Consumer;
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController;
|
import org.moire.ultrasonic.service.MediaPlayerController;
|
||||||
@ -70,6 +71,7 @@ public class SettingsFragment extends PreferenceFragment
|
|||||||
private PreferenceCategory serversCategory;
|
private PreferenceCategory serversCategory;
|
||||||
private Preference resumeOnBluetoothDevice;
|
private Preference resumeOnBluetoothDevice;
|
||||||
private Preference pauseOnBluetoothDevice;
|
private Preference pauseOnBluetoothDevice;
|
||||||
|
private CheckBoxPreference debugLogToFile;
|
||||||
|
|
||||||
private SharedPreferences settings;
|
private SharedPreferences settings;
|
||||||
|
|
||||||
@ -118,6 +120,7 @@ public class SettingsFragment extends PreferenceFragment
|
|||||||
serversCategory = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_SERVERS_KEY);
|
serversCategory = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_SERVERS_KEY);
|
||||||
resumeOnBluetoothDevice = findPreference(Constants.PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE);
|
resumeOnBluetoothDevice = findPreference(Constants.PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE);
|
||||||
pauseOnBluetoothDevice = findPreference(Constants.PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE);
|
pauseOnBluetoothDevice = findPreference(Constants.PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE);
|
||||||
|
debugLogToFile = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_DEBUG_LOG_TO_FILE);
|
||||||
|
|
||||||
sharingDefaultGreeting.setText(Util.getShareGreeting(getActivity()));
|
sharingDefaultGreeting.setText(Util.getShareGreeting(getActivity()));
|
||||||
setupClearSearchPreference();
|
setupClearSearchPreference();
|
||||||
@ -171,6 +174,8 @@ public class SettingsFragment extends PreferenceFragment
|
|||||||
setBluetoothPreferences(sharedPreferences.getBoolean(key, true));
|
setBluetoothPreferences(sharedPreferences.getBoolean(key, true));
|
||||||
} else if (Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY.equals(key)) {
|
} else if (Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY.equals(key)) {
|
||||||
setImageLoaderConcurrency(Integer.parseInt(sharedPreferences.getString(key, "5")));
|
setImageLoaderConcurrency(Integer.parseInt(sharedPreferences.getString(key, "5")));
|
||||||
|
} else if (Constants.PREFERENCES_KEY_DEBUG_LOG_TO_FILE.equals(key)) {
|
||||||
|
setDebugLogToFile(sharedPreferences.getBoolean(key, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,6 +420,13 @@ public class SettingsFragment extends PreferenceFragment
|
|||||||
sendBluetoothAlbumArt.setChecked(false);
|
sendBluetoothAlbumArt.setChecked(false);
|
||||||
sendBluetoothAlbumArt.setEnabled(false);
|
sendBluetoothAlbumArt.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debugLogToFile.isChecked()) {
|
||||||
|
debugLogToFile.setSummary(getString(R.string.settings_debug_log_path,
|
||||||
|
FileUtil.getUltrasonicDirectory(getActivity()), FileLoggerTree.FILENAME));
|
||||||
|
} else {
|
||||||
|
debugLogToFile.setSummary("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setImageLoaderConcurrency(int concurrency) {
|
private static void setImageLoaderConcurrency(int concurrency) {
|
||||||
@ -482,4 +494,47 @@ public class SettingsFragment extends PreferenceFragment
|
|||||||
// Clear download queue.
|
// Clear download queue.
|
||||||
mediaPlayerControllerLazy.getValue().clear();
|
mediaPlayerControllerLazy.getValue().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setDebugLogToFile(boolean writeLog) {
|
||||||
|
if (writeLog) {
|
||||||
|
FileLoggerTree.Companion.plantToTimberForest(getActivity().getApplicationContext());
|
||||||
|
Timber.i("Enabled debug logging to file");
|
||||||
|
} else {
|
||||||
|
FileLoggerTree.Companion.uprootFromTimberForest();
|
||||||
|
Timber.i("Disabled debug logging to file");
|
||||||
|
|
||||||
|
int fileNum = FileLoggerTree.Companion.getLogFileNumber(getActivity());
|
||||||
|
long fileSize = FileLoggerTree.Companion.getLogFileSizes(getActivity());
|
||||||
|
String message = getString(R.string.settings_debug_log_summary,
|
||||||
|
String.valueOf(fileNum),
|
||||||
|
String.valueOf(Math.ceil(fileSize / 1000000d)),
|
||||||
|
FileUtil.getUltrasonicDirectory(getActivity()));
|
||||||
|
|
||||||
|
new AlertDialog.Builder(getActivity())
|
||||||
|
.setMessage(message)
|
||||||
|
.setIcon(android.R.drawable.ic_dialog_info)
|
||||||
|
.setNegativeButton(R.string.settings_debug_log_keep, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
dialogInterface.cancel();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setPositiveButton(R.string.settings_debug_log_delete, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
FileLoggerTree.Companion.deleteLogFiles(getActivity());
|
||||||
|
Timber.i("Deleted debug log files");
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
new AlertDialog.Builder(getActivity()).setMessage(R.string.settings_debug_log_deleted)
|
||||||
|
.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
}
|
||||||
|
}).create().show();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create().show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,6 +134,7 @@ public final class Constants
|
|||||||
public static final String PREFERENCES_KEY_FIRST_RUN_EXECUTED = "firstRunExecuted";
|
public static final String PREFERENCES_KEY_FIRST_RUN_EXECUTED = "firstRunExecuted";
|
||||||
public static final String PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE = "resumeOnBluetoothDevice";
|
public static final String PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE = "resumeOnBluetoothDevice";
|
||||||
public static final String PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE = "pauseOnBluetoothDevice";
|
public static final String PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE = "pauseOnBluetoothDevice";
|
||||||
|
public static final String PREFERENCES_KEY_DEBUG_LOG_TO_FILE = "debugLogToFile";
|
||||||
|
|
||||||
public static final int PREFERENCE_VALUE_ALL = 0;
|
public static final int PREFERENCE_VALUE_ALL = 0;
|
||||||
public static final int PREFERENCE_VALUE_A2DP = 1;
|
public static final int PREFERENCE_VALUE_A2DP = 1;
|
||||||
|
@ -1457,4 +1457,11 @@ public class Util
|
|||||||
SharedPreferences preferences = getPreferences(context);
|
SharedPreferences preferences = getPreferences(context);
|
||||||
return preferences.getInt(Constants.PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE, Constants.PREFERENCE_VALUE_A2DP);
|
return preferences.getInt(Constants.PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE, Constants.PREFERENCE_VALUE_A2DP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean getDebugLogToFile(Context context)
|
||||||
|
{
|
||||||
|
SharedPreferences preferences = getPreferences(context);
|
||||||
|
return preferences.getBoolean(Constants.PREFERENCES_KEY_DEBUG_LOG_TO_FILE, false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package org.moire.ultrasonic.app
|
|||||||
|
|
||||||
import androidx.multidex.MultiDexApplication
|
import androidx.multidex.MultiDexApplication
|
||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.android.ext.koin.androidLogger
|
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
import org.koin.core.logger.Level
|
import org.koin.core.logger.Level
|
||||||
import org.moire.ultrasonic.BuildConfig
|
import org.moire.ultrasonic.BuildConfig
|
||||||
@ -13,8 +12,8 @@ import org.moire.ultrasonic.di.featureFlagsModule
|
|||||||
import org.moire.ultrasonic.di.mediaPlayerModule
|
import org.moire.ultrasonic.di.mediaPlayerModule
|
||||||
import org.moire.ultrasonic.di.musicServiceModule
|
import org.moire.ultrasonic.di.musicServiceModule
|
||||||
import org.moire.ultrasonic.log.FileLoggerTree
|
import org.moire.ultrasonic.log.FileLoggerTree
|
||||||
import org.moire.ultrasonic.log.TimberKoinLogger
|
|
||||||
import org.moire.ultrasonic.log.timberLogger
|
import org.moire.ultrasonic.log.timberLogger
|
||||||
|
import org.moire.ultrasonic.util.Util
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import timber.log.Timber.DebugTree
|
import timber.log.Timber.DebugTree
|
||||||
|
|
||||||
@ -24,7 +23,9 @@ class UApp : MultiDexApplication() {
|
|||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Timber.plant(DebugTree())
|
Timber.plant(DebugTree())
|
||||||
Timber.plant(FileLoggerTree(this))
|
}
|
||||||
|
if (Util.getDebugLogToFile(this)) {
|
||||||
|
FileLoggerTree.plantToTimberForest(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
startKoin {
|
startKoin {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
@file:JvmName("MusicServiceModule")
|
@file:JvmName("MusicServiceModule")
|
||||||
package org.moire.ultrasonic.di
|
package org.moire.ultrasonic.di
|
||||||
|
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.core.qualifier.named
|
import org.koin.core.qualifier.named
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
@ -1,35 +1,104 @@
|
|||||||
package org.moire.ultrasonic.log
|
package org.moire.ultrasonic.log
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileWriter
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
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
|
|
||||||
import java.io.FileWriter
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Timber Tree which can be used to log to a file
|
* A Timber Tree which can be used to log to a file
|
||||||
* Subclass of the DebugTree so it inherits the Tag handling
|
* Subclass of the DebugTree so it inherits the Tag handling
|
||||||
*/
|
*/
|
||||||
class FileLoggerTree(val context: Context) : Timber.DebugTree() {
|
class FileLoggerTree(val context: Context) : Timber.DebugTree() {
|
||||||
private val filename = "ultrasonic.log"
|
private val dateFormat = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a log entry to file
|
||||||
|
*/
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
var file: File? = null
|
|
||||||
var writer: FileWriter? = null
|
var writer: FileWriter? = null
|
||||||
|
callNum++
|
||||||
try {
|
try {
|
||||||
file = File(FileUtil.getUltrasonicDirectory(context), filename)
|
getNextLogFile()
|
||||||
writer = FileWriter(file, true)
|
writer = FileWriter(file, true)
|
||||||
val exceptionString = t?.toString() ?: "";
|
val exceptionString = t?.toString() ?: ""
|
||||||
writer.write("${logLevelToString(priority)} $tag $message $exceptionString\n")
|
val time: String = dateFormat.format(Date())
|
||||||
|
synchronized(file!!) {
|
||||||
|
writer.write(
|
||||||
|
"$time: ${logLevelToString(priority)} $tag $message $exceptionString\n"
|
||||||
|
)
|
||||||
writer.flush()
|
writer.flush()
|
||||||
|
}
|
||||||
} catch (x: Throwable) {
|
} catch (x: Throwable) {
|
||||||
super.e(x, "Failed to write log to %s", file)
|
// Using base class DebugTree here, we don't want to try to log this into file
|
||||||
|
super.log(6, TAG, String.format("Failed to write log to %s", file), x)
|
||||||
} finally {
|
} finally {
|
||||||
if (writer != null) Util.close(writer)
|
if (writer != null) Util.close(writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file to log into
|
||||||
|
* This function also rotates the log files periodically, when they reach the predefined size
|
||||||
|
*/
|
||||||
|
private fun getNextLogFile() {
|
||||||
|
if (file == null) {
|
||||||
|
synchronized(this) {
|
||||||
|
if (file != null) return
|
||||||
|
getNumberedFile(false)
|
||||||
|
// Using base class DebugTree here, we don't want to try to log this into file
|
||||||
|
super.log(4, TAG,String.format("Logging into file %s", file?.name), null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (callNum % 100 == 0) {
|
||||||
|
// Gain some performance by only executing this rarely
|
||||||
|
if (file!!.length() > MAX_LOGFILE_LENGTH) {
|
||||||
|
synchronized(this) {
|
||||||
|
if (file!!.length() <= MAX_LOGFILE_LENGTH) return
|
||||||
|
getNumberedFile(true)
|
||||||
|
// Using base class DebugTree here, we don't want to try to log this into file
|
||||||
|
super.log(
|
||||||
|
4,
|
||||||
|
TAG,
|
||||||
|
String.format("Log file rotated, logging into file %s", file?.name),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the number of log files
|
||||||
|
* @param next: if false, sets the current log file with the greatest number
|
||||||
|
* if true, sets a new file for logging with the next number
|
||||||
|
*/
|
||||||
|
private fun getNumberedFile(next: Boolean) {
|
||||||
|
var fileNum = 1
|
||||||
|
val fileList = getLogFileList(context)
|
||||||
|
|
||||||
|
if (!fileList.isNullOrEmpty()) {
|
||||||
|
fileList.sortByDescending { t -> t.name }
|
||||||
|
val lastFile = fileList[0]
|
||||||
|
val number = fileNumberRegex.find(lastFile.name)?.groups?.get(1)?.value
|
||||||
|
if (number != null) {
|
||||||
|
fileNum = number.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next) fileNum++
|
||||||
|
file = File(
|
||||||
|
FileUtil.getUltrasonicDirectory(context),
|
||||||
|
FILENAME.replace("*", fileNum.toString())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun logLevelToString(logLevel: Int): String {
|
private fun logLevelToString(logLevel: Int): String {
|
||||||
return when (logLevel) {
|
return when (logLevel) {
|
||||||
2 -> "V"
|
2 -> "V"
|
||||||
@ -41,4 +110,60 @@ class FileLoggerTree(val context: Context) : Timber.DebugTree() {
|
|||||||
else -> "U"
|
else -> "U"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TAG = FileLoggerTree::class.simpleName
|
||||||
|
@Volatile private var file: File? = null
|
||||||
|
const val FILENAME = "ultrasonic.*.log"
|
||||||
|
private val fileNameRegex = Regex(
|
||||||
|
FILENAME.replace(".", "\\.").replace("*", "\\d*")
|
||||||
|
)
|
||||||
|
private val fileNumberRegex = Regex(
|
||||||
|
FILENAME.replace(".", "\\.").replace("*", "(\\d*)")
|
||||||
|
)
|
||||||
|
const val MAX_LOGFILE_LENGTH = 10000000
|
||||||
|
var callNum = 0
|
||||||
|
|
||||||
|
fun plantToTimberForest(context: Context) {
|
||||||
|
if (!Timber.forest().any { t -> t is FileLoggerTree }) {
|
||||||
|
Timber.plant(FileLoggerTree(context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun uprootFromTimberForest() {
|
||||||
|
val fileLoggerTree = Timber.forest().singleOrNull { t -> t is FileLoggerTree }
|
||||||
|
?: return
|
||||||
|
Timber.uproot(fileLoggerTree)
|
||||||
|
file = null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLogFileNumber(context: Context): Int {
|
||||||
|
val fileList = getLogFileList(context)
|
||||||
|
if (!fileList.isNullOrEmpty()) return fileList.size
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLogFileSizes(context: Context): Long {
|
||||||
|
var sizeSum: Long = 0
|
||||||
|
val fileList = getLogFileList(context)
|
||||||
|
if (fileList.isNullOrEmpty()) return sizeSum
|
||||||
|
for (file in fileList) {
|
||||||
|
sizeSum += file.length()
|
||||||
|
}
|
||||||
|
return sizeSum
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteLogFiles(context: Context) {
|
||||||
|
val fileList = getLogFileList(context)
|
||||||
|
if (fileList.isNullOrEmpty()) return
|
||||||
|
for (file in fileList) {
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLogFileList(context: Context): Array<File> {
|
||||||
|
val directory = FileUtil.getUltrasonicDirectory(context)
|
||||||
|
return directory.listFiles { t -> t.name.matches(fileNameRegex) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -401,6 +401,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||||
<string name="permissions.message_box_title">Warning</string>
|
<string name="permissions.message_box_title">Warning</string>
|
||||||
|
@ -402,6 +402,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">Todos los dispositivos Bluetooth</string>
|
<string name="settings.playback.bluetooth_all">Todos los dispositivos Bluetooth</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Solo dispositivos de audio (A2DP)</string>
|
<string name="settings.playback.bluetooth_a2dp">Solo dispositivos de audio (A2DP)</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Deshabilitado</string>
|
<string name="settings.playback.bluetooth_disabled">Deshabilitado</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic no puede acceder a la caché de los ficheros de música. La ubicación de la caché se restableció a la ruta predeterminada.</string>
|
<string name="permissions.access_error">Ultrasonic no puede acceder a la caché de los ficheros de música. La ubicación de la caché se restableció a la ruta predeterminada.</string>
|
||||||
<string name="permissions.message_box_title">Atención</string>
|
<string name="permissions.message_box_title">Atención</string>
|
||||||
|
@ -402,6 +402,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||||
<string name="permissions.message_box_title">Warning</string>
|
<string name="permissions.message_box_title">Warning</string>
|
||||||
|
@ -402,6 +402,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">Minden Bluetooth eszköz</string>
|
<string name="settings.playback.bluetooth_all">Minden Bluetooth eszköz</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Csak audio (A2DP) eszközök</string>
|
<string name="settings.playback.bluetooth_a2dp">Csak audio (A2DP) eszközök</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Kikapcsolva</string>
|
<string name="settings.playback.bluetooth_disabled">Kikapcsolva</string>
|
||||||
|
<string name="settings.debug.title">Hibakeresési lehetőségek</string>
|
||||||
|
<string name="settings.debug.log_to_file">Hibakeresési napló írása fájlba</string>
|
||||||
|
<string name="settings.debug.log_path">A naplófájlok elérhetőek a következő helyen: %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">%1$s napló fájl ~%2$s MB méretben található a %3$s könyvtárban. Meg szeretnéd atrtani ezeket?</string>
|
||||||
|
<string name="settings.debug.log_keep">Fájlok megtartása</string>
|
||||||
|
<string name="settings.debug.log_delete">Fájlok törlése</string>
|
||||||
|
<string name="settings.debug.log_deleted">Naplófájlok törölve.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Az Ultrasonic nem éri el a zenei fájl gyorsítótárat. A gyorsítótár helye visszaállítva az alapbeállításra.</string>
|
<string name="permissions.access_error">Az Ultrasonic nem éri el a zenei fájl gyorsítótárat. A gyorsítótár helye visszaállítva az alapbeállításra.</string>
|
||||||
<string name="permissions.message_box_title">Figyelem</string>
|
<string name="permissions.message_box_title">Figyelem</string>
|
||||||
|
@ -402,6 +402,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||||
<string name="permissions.message_box_title">Warning</string>
|
<string name="permissions.message_box_title">Warning</string>
|
||||||
|
@ -402,6 +402,13 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników
|
|||||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||||
<string name="permissions.message_box_title">Warning</string>
|
<string name="permissions.message_box_title">Warning</string>
|
||||||
|
@ -402,6 +402,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||||
<string name="permissions.message_box_title">Warning</string>
|
<string name="permissions.message_box_title">Warning</string>
|
||||||
|
@ -402,6 +402,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||||
<string name="permissions.message_box_title">Warning</string>
|
<string name="permissions.message_box_title">Warning</string>
|
||||||
|
@ -405,6 +405,13 @@
|
|||||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||||
|
<string name="settings.debug.title">Debug options</string>
|
||||||
|
<string name="settings.debug.log_to_file">Write debug log to file</string>
|
||||||
|
<string name="settings.debug.log_path">The log files are available at %1$s/%2$s</string>
|
||||||
|
<string name="settings.debug.log_summary">There are %1$s log files taking up ~%2$s MB space in the %3$s directory. Do you want to keep these?</string>
|
||||||
|
<string name="settings.debug.log_keep">Keep files</string>
|
||||||
|
<string name="settings.debug.log_delete">Delete files</string>
|
||||||
|
<string name="settings.debug.log_deleted">Deleted log files.</string>
|
||||||
|
|
||||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||||
<string name="permissions.message_box_title">Warning</string>
|
<string name="permissions.message_box_title">Warning</string>
|
||||||
|
@ -305,7 +305,14 @@
|
|||||||
a:title="@string/feature_flags_five_star_rating_title"
|
a:title="@string/feature_flags_five_star_rating_title"
|
||||||
a:summary="@string/feature_flags_five_star_rating_description"
|
a:summary="@string/feature_flags_five_star_rating_description"
|
||||||
/>
|
/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
<PreferenceCategory a:title="@string/settings.debug.title">
|
||||||
|
<CheckBoxPreference
|
||||||
|
a:defaultValue="false"
|
||||||
|
a:key="debugLogToFile"
|
||||||
|
a:title="@string/settings.debug.log_to_file"
|
||||||
|
a:summary=""
|
||||||
|
/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
Loading…
x
Reference in New Issue
Block a user