Merge pull request #600 from ultrasonic/permission_failed
Migrate Permission utitlity to Kotlin, increase min SDK to 17
This commit is contained in:
commit
784c65f96d
|
@ -1,5 +1,5 @@
|
|||
ext.versions = [
|
||||
minSdk : 14,
|
||||
minSdk : 17,
|
||||
targetSdk : 29,
|
||||
compileSdk : 29,
|
||||
// You need to run ./gradlew wrapper after updating the version
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,7 +27,9 @@
|
|||
android:theme="@style/NoActionBar"
|
||||
android:name=".app.UApp"
|
||||
android:label="@string/common.appname"
|
||||
android:usesCleartextTraffic="true">
|
||||
android:usesCleartextTraffic="true"
|
||||
android:supportsRtl="false"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<meta-data android:name="com.google.android.gms.car.application"
|
||||
android:resource="@xml/automotive_app_desc"/>
|
||||
|
|
|
@ -144,7 +144,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||
setupServersCategory();
|
||||
sharingDefaultGreeting.setText(Settings.getShareGreeting());
|
||||
setupClearSearchPreference();
|
||||
setupGaplessControlSettingsV14();
|
||||
setupFeatureFlagsPreferences();
|
||||
setupCacheLocationPreference();
|
||||
setupBluetoothDevicePreferences();
|
||||
|
@ -224,8 +223,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||
}
|
||||
|
||||
private void setupCacheLocationPreference() {
|
||||
cacheLocation.setSummary(settings.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION,
|
||||
FileUtil.getDefaultMusicDirectory().getPath()));
|
||||
cacheLocation.setSummary(Settings.getCacheLocation());
|
||||
|
||||
cacheLocation.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
|
@ -376,24 +374,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||
|
||||
}
|
||||
|
||||
private void setupGaplessControlSettingsV14() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
PreferenceCategory playbackControlSettings =
|
||||
findPreference(Constants.PREFERENCES_KEY_PLAYBACK_CONTROL_SETTINGS);
|
||||
CheckBoxPreference gaplessPlaybackEnabled =
|
||||
findPreference(Constants.PREFERENCES_KEY_GAPLESS_PLAYBACK);
|
||||
|
||||
if (gaplessPlaybackEnabled != null) {
|
||||
gaplessPlaybackEnabled.setChecked(false);
|
||||
gaplessPlaybackEnabled.setEnabled(false);
|
||||
|
||||
if (playbackControlSettings != null) {
|
||||
playbackControlSettings.removePreference(gaplessPlaybackEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupServersCategory() {
|
||||
addServerPreference.setPersistent(false);
|
||||
addServerPreference.setTitle(getResources().getString(R.string.settings_server_manage_servers));
|
||||
|
@ -431,8 +411,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||
sharingDefaultExpiration.setSummary(sharingDefaultExpiration.getText());
|
||||
sharingDefaultDescription.setSummary(sharingDefaultDescription.getText());
|
||||
sharingDefaultGreeting.setSummary(sharingDefaultGreeting.getText());
|
||||
cacheLocation.setSummary(settings.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION,
|
||||
FileUtil.getDefaultMusicDirectory().getPath()));
|
||||
cacheLocation.setSummary(Settings.getCacheLocation());
|
||||
|
||||
if (!mediaButtonsEnabled.isChecked()) {
|
||||
lockScreenEnabled.setChecked(false);
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
package org.moire.ultrasonic.util;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.PermissionChecker;
|
||||
|
||||
import com.karumi.dexter.Dexter;
|
||||
import com.karumi.dexter.MultiplePermissionsReport;
|
||||
import com.karumi.dexter.PermissionToken;
|
||||
import com.karumi.dexter.listener.DexterError;
|
||||
import com.karumi.dexter.listener.PermissionRequest;
|
||||
import com.karumi.dexter.listener.PermissionRequestErrorListener;
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;
|
||||
|
||||
|
||||
/**
|
||||
* Contains static functions for Permission handling
|
||||
*/
|
||||
public class PermissionUtil {
|
||||
|
||||
private Context activityContext;
|
||||
private final Context applicationContext;
|
||||
|
||||
public PermissionUtil(Context context) {
|
||||
applicationContext = context;
|
||||
}
|
||||
|
||||
public interface PermissionRequestFinishedCallback {
|
||||
void onPermissionRequestFinished(boolean hasPermission);
|
||||
}
|
||||
|
||||
public void ForegroundApplicationStarted(Context context) {
|
||||
this.activityContext = context;
|
||||
}
|
||||
|
||||
public void ForegroundApplicationStopped() {
|
||||
activityContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be used to handle file access permission failures.
|
||||
*
|
||||
* It will check if the failure is because the necessary permissions aren't available,
|
||||
* and it will request them, if necessary.
|
||||
*
|
||||
* @param callback callback function to execute after the permission request is finished
|
||||
*/
|
||||
public void handlePermissionFailed(@Nullable final PermissionRequestFinishedCallback callback) {
|
||||
String currentCachePath = Settings.getPreferences().getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, FileUtil.getDefaultMusicDirectory().getPath());
|
||||
String defaultCachePath = FileUtil.getDefaultMusicDirectory().getPath();
|
||||
|
||||
// Ultrasonic can do nothing about this error when the Music Directory is already set to the default.
|
||||
if (currentCachePath.compareTo(defaultCachePath) == 0) return;
|
||||
|
||||
if ((PermissionChecker.checkSelfPermission(applicationContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_DENIED) ||
|
||||
(PermissionChecker.checkSelfPermission(applicationContext, Manifest.permission.READ_EXTERNAL_STORAGE) == PERMISSION_DENIED)) {
|
||||
// While we request permission, the Music Directory is temporarily reset to its default location
|
||||
setCacheLocation(applicationContext, FileUtil.getDefaultMusicDirectory().getPath());
|
||||
// If the application is not running, we can't notify the user
|
||||
if (activityContext == null) return;
|
||||
requestFailedPermission(activityContext, currentCachePath, callback);
|
||||
} else {
|
||||
setCacheLocation(applicationContext, FileUtil.getDefaultMusicDirectory().getPath());
|
||||
// If the application is not running, we can't notify the user
|
||||
if (activityContext != null) {
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showWarning(activityContext, activityContext.getString(R.string.permissions_message_box_title), activityContext.getString(R.string.permissions_access_error), null);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.onPermissionRequestFinished(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function requests permission to access the filesystem.
|
||||
* It can be used to request the permission initially, e.g. when the user decides to use a non-default folder for the cache
|
||||
* @param context context for the operation
|
||||
* @param callback callback function to execute after the permission request is finished
|
||||
*/
|
||||
public static void requestInitialPermission(final Context context, final PermissionRequestFinishedCallback callback) {
|
||||
Dexter.withContext(context)
|
||||
.withPermissions(
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
.withListener(new MultiplePermissionsListener() {
|
||||
@Override
|
||||
public void onPermissionsChecked(MultiplePermissionsReport report) {
|
||||
if (report.areAllPermissionsGranted()) {
|
||||
Timber.i("Permission granted to read / write external storage");
|
||||
if (callback != null) callback.onPermissionRequestFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (report.isAnyPermissionPermanentlyDenied()) {
|
||||
Timber.i("Found permanently denied permission to read / write external storage, offering settings");
|
||||
showSettingsDialog(context);
|
||||
if (callback != null) callback.onPermissionRequestFinished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Timber.i("At least one permission is missing to read / write external storage");
|
||||
showWarning(context, context.getString(R.string.permissions_message_box_title),
|
||||
context.getString(R.string.permissions_rationale_description_initial), null);
|
||||
if (callback != null) callback.onPermissionRequestFinished(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
|
||||
showWarning(context, context.getString(R.string.permissions_rationale_title),
|
||||
context.getString(R.string.permissions_rationale_description_initial), token);
|
||||
}
|
||||
}).withErrorListener(new PermissionRequestErrorListener() {
|
||||
@Override
|
||||
public void onError(DexterError error) {
|
||||
Timber.e("An error has occurred during checking permissions with Dexter: %s", error.toString());
|
||||
}
|
||||
})
|
||||
.check();
|
||||
}
|
||||
|
||||
private static void setCacheLocation(Context context, String cacheLocation) {
|
||||
Settings.getPreferences().edit()
|
||||
.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, cacheLocation)
|
||||
.apply();
|
||||
}
|
||||
|
||||
private static void requestFailedPermission(final Context context, final String cacheLocation, final PermissionRequestFinishedCallback callback) {
|
||||
Dexter.withContext(context)
|
||||
.withPermissions(
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
.withListener(new MultiplePermissionsListener() {
|
||||
@Override
|
||||
public void onPermissionsChecked(MultiplePermissionsReport report) {
|
||||
if (report.areAllPermissionsGranted()) {
|
||||
Timber.i("Permission granted to use cache directory %s", cacheLocation);
|
||||
setCacheLocation(context, cacheLocation);
|
||||
if (callback != null) callback.onPermissionRequestFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (report.isAnyPermissionPermanentlyDenied()) {
|
||||
Timber.i("Found permanently denied permission to use cache directory %s, offering settings", cacheLocation);
|
||||
showSettingsDialog(context);
|
||||
if (callback != null) callback.onPermissionRequestFinished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Timber.i("At least one permission is missing to use directory %s ", cacheLocation);
|
||||
setCacheLocation(context, FileUtil.getDefaultMusicDirectory().getPath());
|
||||
showWarning(context, context.getString(R.string.permissions_message_box_title),
|
||||
context.getString(R.string.permissions_permission_missing), null);
|
||||
if (callback != null) callback.onPermissionRequestFinished(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
|
||||
showWarning(context, context.getString(R.string.permissions_rationale_title),
|
||||
context.getString(R.string.permissions_rationale_description_failed), token);
|
||||
}
|
||||
}).withErrorListener(new PermissionRequestErrorListener() {
|
||||
@Override
|
||||
public void onError(DexterError error) {
|
||||
Timber.e("An error has occurred during checking permissions with Dexter: %s", error.toString());
|
||||
}
|
||||
})
|
||||
.check();
|
||||
}
|
||||
|
||||
private static void showSettingsDialog(final Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.Theme_AppCompat_Dialog);
|
||||
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
builder.setTitle(context.getString(R.string.permissions_permanent_denial_title));
|
||||
builder.setMessage(context.getString(R.string.permissions_permanent_denial_description));
|
||||
|
||||
builder.setPositiveButton(context.getString(R.string.permissions_open_settings), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
openSettings(context);
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNegativeButton(context.getString(R.string.common_cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setCacheLocation(context, FileUtil.getDefaultMusicDirectory().getPath());
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private static void openSettings(Context context) {
|
||||
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
i.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
i.setData(Uri.parse("package:" + context.getPackageName()));
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
private static void showWarning(Context context, String title, String text, final PermissionToken token) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.Theme_AppCompat_Dialog);
|
||||
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
builder.setTitle(title);
|
||||
builder.setMessage(text);
|
||||
builder.setPositiveButton(context.getString(R.string.common_ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
if (token != null) token.continuePermissionRequest();
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
}
|
|
@ -83,7 +83,7 @@ class NavigationActivity : AppCompatActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setUncaughtExceptionHandler()
|
||||
permissionUtil.ForegroundApplicationStarted(this)
|
||||
permissionUtil.onForegroundApplicationStarted(this)
|
||||
Util.applyTheme(this)
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -198,7 +198,7 @@ class NavigationActivity : AppCompatActivity() {
|
|||
nowPlayingEventDistributor.unsubscribe(nowPlayingEventListener)
|
||||
themeChangedEventDistributor.unsubscribe(themeChangedEventListener)
|
||||
imageLoaderProvider.clearImageLoader()
|
||||
permissionUtil.ForegroundApplicationStopped()
|
||||
permissionUtil.onForegroundApplicationStopped()
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
|
@ -304,12 +304,7 @@ class NavigationActivity : AppCompatActivity() {
|
|||
PreferenceManager.setDefaultValues(this, R.xml.settings, false)
|
||||
val preferences = Settings.preferences
|
||||
if (!preferences.contains(Constants.PREFERENCES_KEY_CACHE_LOCATION)) {
|
||||
val editor = preferences.edit()
|
||||
editor.putString(
|
||||
Constants.PREFERENCES_KEY_CACHE_LOCATION,
|
||||
FileUtil.defaultMusicDirectory.path
|
||||
)
|
||||
editor.apply()
|
||||
Settings.cacheLocation = FileUtil.defaultMusicDirectory.path
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -415,10 +415,9 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
|||
}
|
||||
|
||||
Util.showDialog(
|
||||
activity,
|
||||
android.R.drawable.ic_dialog_info,
|
||||
R.string.settings_testing_ok,
|
||||
dialogText
|
||||
context = requireActivity(),
|
||||
titleId = R.string.settings_testing_ok,
|
||||
message = dialogText
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -485,11 +485,7 @@ class LocalMediaPlayer : KoinComponent {
|
|||
try {
|
||||
setNextPlayerState(PlayerState.PREPARED)
|
||||
if (Settings.gaplessPlayback &&
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
|
||||
(
|
||||
playerState === PlayerState.STARTED ||
|
||||
playerState === PlayerState.PAUSED
|
||||
)
|
||||
(playerState === PlayerState.STARTED || playerState === PlayerState.PAUSED)
|
||||
) {
|
||||
mediaPlayer.setNextMediaPlayer(nextMediaPlayer)
|
||||
nextSetup = true
|
||||
|
|
|
@ -253,9 +253,8 @@ object FileUtil {
|
|||
@JvmStatic
|
||||
val musicDirectory: File
|
||||
get() {
|
||||
val path = Settings.preferences
|
||||
.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, defaultMusicDirectory.path)
|
||||
val dir = File(path!!)
|
||||
val path = Settings.cacheLocation
|
||||
val dir = File(path)
|
||||
val hasAccess = ensureDirectoryExistsAndIsReadWritable(dir)
|
||||
if (!hasAccess) permissionUtil.value.handlePermissionFailed(null)
|
||||
return if (hasAccess) dir else defaultMusicDirectory
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
package org.moire.ultrasonic.util
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.core.content.PermissionChecker
|
||||
import com.karumi.dexter.Dexter
|
||||
import com.karumi.dexter.MultiplePermissionsReport
|
||||
import com.karumi.dexter.PermissionToken
|
||||
import com.karumi.dexter.listener.PermissionRequest
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.util.FileUtil.defaultMusicDirectory
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Contains static functions for Permission handling
|
||||
*/
|
||||
class PermissionUtil(private val applicationContext: Context) {
|
||||
private var activityContext: Context? = null
|
||||
|
||||
interface PermissionRequestFinishedCallback {
|
||||
fun onPermissionRequestFinished(hasPermission: Boolean)
|
||||
}
|
||||
|
||||
fun onForegroundApplicationStarted(context: Context?) {
|
||||
activityContext = context
|
||||
}
|
||||
|
||||
fun onForegroundApplicationStopped() {
|
||||
activityContext = null
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be used to handle file access permission failures.
|
||||
*
|
||||
* It will check if the failure is because the necessary permissions aren't available,
|
||||
* and it will request them, if necessary.
|
||||
*
|
||||
* @param callback callback function to execute after the permission request is finished
|
||||
*/
|
||||
fun handlePermissionFailed(callback: PermissionRequestFinishedCallback?) {
|
||||
val currentCachePath = Settings.cacheLocation
|
||||
val defaultCachePath = defaultMusicDirectory.path
|
||||
|
||||
// Ultrasonic can do nothing about this error when the Music Directory is already set to the default.
|
||||
if (currentCachePath.compareTo(defaultCachePath) == 0) return
|
||||
|
||||
if (PermissionChecker.checkSelfPermission(
|
||||
applicationContext,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) == PermissionChecker.PERMISSION_DENIED ||
|
||||
PermissionChecker.checkSelfPermission(
|
||||
applicationContext,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PermissionChecker.PERMISSION_DENIED
|
||||
) {
|
||||
// While we request permission, the Music Directory is temporarily reset to its default location
|
||||
Settings.cacheLocation = defaultMusicDirectory.path
|
||||
// If the application is not running, we can't notify the user
|
||||
if (activityContext == null) return
|
||||
requestFailedPermission(activityContext!!, currentCachePath, callback)
|
||||
} else {
|
||||
Settings.cacheLocation = defaultMusicDirectory.path
|
||||
// If the application is not running, we can't notify the user
|
||||
if (activityContext != null) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
showWarning(
|
||||
activityContext!!,
|
||||
activityContext!!.getString(R.string.permissions_message_box_title),
|
||||
activityContext!!.getString(R.string.permissions_access_error),
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
callback?.onPermissionRequestFinished(false)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* This function requests permission to access the filesystem.
|
||||
* It can be used to request the permission initially, e.g. when the user decides to
|
||||
* use a non-default folder for the cache
|
||||
* @param context context for the operation
|
||||
* @param callback callback function to execute after the permission request is finished
|
||||
*/
|
||||
@JvmStatic
|
||||
fun requestInitialPermission(
|
||||
context: Context,
|
||||
callback: PermissionRequestFinishedCallback?
|
||||
) {
|
||||
Dexter.withContext(context)
|
||||
.withPermissions(
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
)
|
||||
.withListener(object : MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport) {
|
||||
if (report.areAllPermissionsGranted()) {
|
||||
Timber.i("R/W permission granted for external storage")
|
||||
callback?.onPermissionRequestFinished(true)
|
||||
return
|
||||
}
|
||||
if (report.isAnyPermissionPermanentlyDenied) {
|
||||
Timber.i(
|
||||
"R/W permission is permanently denied for external storage"
|
||||
)
|
||||
showSettingsDialog(context)
|
||||
callback?.onPermissionRequestFinished(false)
|
||||
return
|
||||
}
|
||||
Timber.i("R/W permission is missing for external storage")
|
||||
showWarning(
|
||||
context,
|
||||
context.getString(R.string.permissions_message_box_title),
|
||||
context.getString(R.string.permissions_rationale_description_initial),
|
||||
null
|
||||
)
|
||||
callback?.onPermissionRequestFinished(false)
|
||||
}
|
||||
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: List<PermissionRequest>,
|
||||
token: PermissionToken
|
||||
) {
|
||||
showWarning(
|
||||
context,
|
||||
context.getString(R.string.permissions_rationale_title),
|
||||
context.getString(R.string.permissions_rationale_description_initial),
|
||||
token
|
||||
)
|
||||
}
|
||||
}).withErrorListener { error ->
|
||||
Timber.e(
|
||||
"An error has occurred during checking permissions with Dexter: %s",
|
||||
error.toString()
|
||||
)
|
||||
}
|
||||
.check()
|
||||
}
|
||||
|
||||
private fun requestFailedPermission(
|
||||
context: Context,
|
||||
cacheLocation: String?,
|
||||
callback: PermissionRequestFinishedCallback?
|
||||
) {
|
||||
Dexter.withContext(context)
|
||||
.withPermissions(
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
)
|
||||
.withListener(object : MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport) {
|
||||
if (report.areAllPermissionsGranted()) {
|
||||
Timber.i("Permission granted to use cache directory %s", cacheLocation)
|
||||
|
||||
if (cacheLocation != null) {
|
||||
Settings.cacheLocation = cacheLocation
|
||||
}
|
||||
callback?.onPermissionRequestFinished(true)
|
||||
return
|
||||
}
|
||||
if (report.isAnyPermissionPermanentlyDenied) {
|
||||
Timber.i(
|
||||
"R/W permission for cache directory %s was permanently denied",
|
||||
cacheLocation
|
||||
)
|
||||
showSettingsDialog(context)
|
||||
callback?.onPermissionRequestFinished(false)
|
||||
return
|
||||
}
|
||||
Timber.i(
|
||||
"At least one permission is missing to use directory %s ",
|
||||
cacheLocation
|
||||
)
|
||||
Settings.cacheLocation = defaultMusicDirectory.path
|
||||
showWarning(
|
||||
context, context.getString(R.string.permissions_message_box_title),
|
||||
context.getString(R.string.permissions_permission_missing), null
|
||||
)
|
||||
callback?.onPermissionRequestFinished(false)
|
||||
}
|
||||
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: List<PermissionRequest>,
|
||||
token: PermissionToken
|
||||
) {
|
||||
showWarning(
|
||||
context,
|
||||
context.getString(R.string.permissions_rationale_title),
|
||||
context.getString(R.string.permissions_rationale_description_failed),
|
||||
token
|
||||
)
|
||||
}
|
||||
}).withErrorListener { error ->
|
||||
Timber.e(
|
||||
"An error has occurred during checking permissions with Dexter: %s",
|
||||
error.toString()
|
||||
)
|
||||
}
|
||||
.check()
|
||||
}
|
||||
|
||||
private fun showSettingsDialog(ctx: Context) {
|
||||
|
||||
val builder = Util.createDialog(
|
||||
context = ctx,
|
||||
android.R.drawable.ic_dialog_alert,
|
||||
ctx.getString(R.string.permissions_permanent_denial_title),
|
||||
ctx.getString(R.string.permissions_permanent_denial_description)
|
||||
)
|
||||
|
||||
builder.setPositiveButton(ctx.getString(R.string.permissions_open_settings)) {
|
||||
dialog, _ ->
|
||||
dialog.cancel()
|
||||
openSettings(ctx)
|
||||
}
|
||||
|
||||
builder.setNegativeButton(ctx.getString(R.string.common_cancel)) { dialog, _ ->
|
||||
Settings.cacheLocation = defaultMusicDirectory.path
|
||||
dialog.cancel()
|
||||
}
|
||||
|
||||
builder.show()
|
||||
}
|
||||
|
||||
private fun openSettings(context: Context) {
|
||||
val i = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
i.addCategory(Intent.CATEGORY_DEFAULT)
|
||||
i.data = Uri.parse("package:" + context.packageName)
|
||||
context.startActivity(i)
|
||||
}
|
||||
|
||||
private fun showWarning(
|
||||
context: Context,
|
||||
title: String,
|
||||
text: String,
|
||||
token: PermissionToken?
|
||||
) {
|
||||
|
||||
val builder = Util.createDialog(
|
||||
context = context,
|
||||
android.R.drawable.ic_dialog_alert,
|
||||
title,
|
||||
text
|
||||
)
|
||||
|
||||
builder.setPositiveButton(context.getString(R.string.common_ok)) { dialog, _ ->
|
||||
dialog.cancel()
|
||||
token?.continuePermissionRequest()
|
||||
}
|
||||
builder.show()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,6 +102,23 @@ object Settings {
|
|||
return if (preloadCount == -1) Int.MAX_VALUE else preloadCount
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
var cacheLocation: String
|
||||
get() {
|
||||
return preferences.getString(
|
||||
Constants.PREFERENCES_KEY_CACHE_LOCATION,
|
||||
FileUtil.defaultMusicDirectory.path
|
||||
)!!
|
||||
}
|
||||
set(location) {
|
||||
val editor = preferences.edit()
|
||||
editor.putString(
|
||||
Constants.PREFERENCES_KEY_CACHE_LOCATION,
|
||||
location
|
||||
)
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
val cacheSizeMB: Int
|
||||
get() {
|
||||
|
|
|
@ -393,17 +393,30 @@ object Util {
|
|||
|
||||
// The AlertDialog requires an Activity context, app context is not enough
|
||||
// See https://stackoverflow.com/questions/5436822/
|
||||
fun showDialog(context: Context?, icon: Int, titleId: Int, message: String?) {
|
||||
AlertDialog.Builder(context)
|
||||
fun createDialog(
|
||||
context: Context?,
|
||||
icon: Int = android.R.drawable.ic_dialog_info,
|
||||
title: String,
|
||||
message: String?
|
||||
): AlertDialog.Builder {
|
||||
return AlertDialog.Builder(context)
|
||||
.setIcon(icon)
|
||||
.setTitle(titleId)
|
||||
.setTitle(title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.common_ok) {
|
||||
dialog: DialogInterface,
|
||||
_: Int ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
fun showDialog(
|
||||
context: Context,
|
||||
icon: Int = android.R.drawable.ic_dialog_info,
|
||||
titleId: Int,
|
||||
message: String?
|
||||
) {
|
||||
createDialog(context, icon, context.getString(titleId, ""), message).show()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
android:bottomLeftRadius="44dp" />
|
||||
|
||||
<padding
|
||||
android:paddingLeft="22dp"
|
||||
android:paddingRight="22dp" />
|
||||
android:paddingStart="22dp"
|
||||
android:paddingEnd="22dp" />
|
||||
|
||||
<solid android:color="@color/selected_color_dark" />
|
||||
|
||||
|
|
|
@ -110,8 +110,8 @@
|
|||
a:layout_width="fill_parent"
|
||||
a:layout_height="60dip"
|
||||
a:layout_gravity="bottom|center_horizontal"
|
||||
a:layout_marginLeft="60dip"
|
||||
a:layout_marginRight="60dip"
|
||||
a:layout_marginStart="60dip"
|
||||
a:layout_marginEnd="60dip"
|
||||
a:background="@color/translucent"
|
||||
a:orientation="vertical"/>
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
a:layout_height="64dp"
|
||||
a:layout_gravity="center_horizontal|center_vertical"
|
||||
a:layout_marginStart="6dp"
|
||||
a:layout_marginLeft="6dp"
|
||||
a:layout_marginTop="6dp"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/unknown_album"
|
||||
|
@ -28,13 +27,12 @@
|
|||
a:layout_width="0dp"
|
||||
a:layout_height="74dp"
|
||||
a:layout_marginStart="10dp"
|
||||
a:layout_marginLeft="10dp"
|
||||
a:drawablePadding="6dip"
|
||||
a:gravity="center_vertical"
|
||||
a:minHeight="56dip"
|
||||
a:orientation="vertical"
|
||||
a:paddingLeft="3dip"
|
||||
a:paddingRight="3dip"
|
||||
a:paddingStart="3dip"
|
||||
a:paddingEnd="3dip"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||
app:layout_constraintEnd_toStartOf="@+id/album_star"
|
||||
app:layout_constraintLeft_toRightOf="@+id/album_coverart"
|
||||
|
@ -65,10 +63,8 @@
|
|||
a:layout_width="38dp"
|
||||
a:layout_height="38dp"
|
||||
a:layout_marginStart="16dp"
|
||||
a:layout_marginLeft="16dp"
|
||||
a:layout_marginTop="16dp"
|
||||
a:layout_marginEnd="20dp"
|
||||
a:layout_marginRight="20dp"
|
||||
a:background="@android:color/transparent"
|
||||
a:gravity="center_horizontal"
|
||||
a:src="?attr/star_hollow"
|
||||
|
|
|
@ -9,17 +9,17 @@
|
|||
a:id="@+id/album_coverart"
|
||||
a:layout_width="64dp"
|
||||
a:layout_height="64dp"
|
||||
a:layout_gravity="left|center_vertical"
|
||||
a:paddingLeft="3dip" />
|
||||
a:layout_gravity="start|center_vertical"
|
||||
a:paddingStart="3dip" />
|
||||
|
||||
<LinearLayout
|
||||
a:orientation="vertical"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_weight="1"
|
||||
a:layout_gravity="left|center_vertical"
|
||||
a:paddingLeft="6dip"
|
||||
a:paddingRight="3dip">
|
||||
a:layout_gravity="start|center_vertical"
|
||||
a:paddingStart="6dip"
|
||||
a:paddingEnd="3dip">
|
||||
|
||||
<TextView
|
||||
a:id="@+id/album_title"
|
||||
|
@ -46,6 +46,6 @@
|
|||
a:background="@android:color/transparent"
|
||||
a:src="?attr/star_hollow"
|
||||
a:focusable="false"
|
||||
a:paddingRight="3dip" />
|
||||
a:paddingEnd="3dip" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:minHeight="16sp"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:paddingTop="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
|
@ -57,8 +57,8 @@
|
|||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Artist"
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:minHeight="16sp"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:paddingTop="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
|
@ -58,8 +58,8 @@
|
|||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Artist"
|
||||
|
@ -75,8 +75,8 @@
|
|||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Album"
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:minHeight="16sp"
|
||||
a:paddingLeft="5dip"
|
||||
a:paddingRight="5dip"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingEnd="5dip"
|
||||
a:singleLine="true"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="16sp"
|
||||
|
@ -61,7 +61,7 @@
|
|||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingLeft="5dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
a:text="Artist"
|
||||
a:layout_gravity="center_horizontal"
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:minHeight="16sp"
|
||||
a:paddingLeft="5dip"
|
||||
a:paddingRight="5dip"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingEnd="5dip"
|
||||
a:singleLine="true"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="16sp"
|
||||
|
@ -62,7 +62,7 @@
|
|||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingLeft="5dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
a:text="Artist"
|
||||
a:layout_gravity="center_horizontal"
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
a:minWidth="56dip"
|
||||
a:minHeight="56dip"
|
||||
a:paddingStart="8dip"
|
||||
a:paddingLeft="8dip"
|
||||
a:paddingEnd="8dip"
|
||||
a:paddingRight="8dip"
|
||||
a:text="A"
|
||||
a:textAppearance="?android:attr/textAppearanceLarge"
|
||||
a:textColor="@color/cyan" />
|
||||
|
@ -30,11 +28,8 @@
|
|||
a:layout_gravity="center_horizontal|center_vertical"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginStart="2dp"
|
||||
a:layout_marginLeft="2dp"
|
||||
a:layout_marginEnd="10dp"
|
||||
a:layout_marginRight="10dp"
|
||||
a:layout_toEndOf="@+id/row_section"
|
||||
a:layout_toRightOf="@+id/row_section"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/ic_contact_picture"
|
||||
app:shapeAppearanceOverlay="@style/roundedImageView" />
|
||||
|
@ -44,13 +39,12 @@
|
|||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_toEndOf="@+id/artist_coverart"
|
||||
a:layout_toRightOf="@+id/artist_coverart"
|
||||
a:drawablePadding="6dip"
|
||||
a:gravity="center_vertical"
|
||||
a:minHeight="56dip"
|
||||
a:paddingLeft="3dip"
|
||||
a:paddingRight="3dip"
|
||||
a:layout_marginRight="12dp"
|
||||
a:paddingStart="3dip"
|
||||
a:paddingEnd="3dip"
|
||||
a:layout_marginEnd="12dp"
|
||||
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
</RelativeLayout>
|
|
@ -20,8 +20,8 @@
|
|||
a:id="@+id/chat_username"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="6dip"
|
||||
a:layout_marginRight="6dip"
|
||||
a:layout_marginStart="6dip"
|
||||
a:layout_marginEnd="6dip"
|
||||
a:ellipsize="marquee"
|
||||
a:singleLine="true"
|
||||
a:textIsSelectable="true"
|
||||
|
@ -43,7 +43,7 @@
|
|||
a:id="@+id/chat_time"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="6dip"
|
||||
a:layout_marginStart="6dip"
|
||||
a:singleLine="true"
|
||||
a:textIsSelectable="true"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||
|
@ -53,8 +53,8 @@
|
|||
a:id="@+id/chat_message"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="6dip"
|
||||
a:layout_marginRight="6dip"
|
||||
a:layout_marginStart="6dip"
|
||||
a:layout_marginEnd="6dip"
|
||||
a:textIsSelectable="true"
|
||||
a:linksClickable="true"
|
||||
a:singleLine="false"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
a:id="@+id/chat_username"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginRight="6dip"
|
||||
a:layout_marginEnd="6dip"
|
||||
a:gravity="center_vertical|right"
|
||||
a:layout_gravity="right"
|
||||
a:ellipsize="marquee"
|
||||
|
@ -38,7 +38,7 @@
|
|||
a:id="@+id/chat_time"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="6dip"
|
||||
a:layout_marginStart="6dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_vertical|right"
|
||||
a:textIsSelectable="true"
|
||||
|
@ -49,8 +49,8 @@
|
|||
a:id="@+id/chat_message"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="6dip"
|
||||
a:layout_marginRight="6dip"
|
||||
a:layout_marginStart="6dip"
|
||||
a:layout_marginEnd="6dip"
|
||||
a:linksClickable="true"
|
||||
a:singleLine="false"
|
||||
a:autoLink="all"
|
||||
|
|
|
@ -110,8 +110,8 @@
|
|||
a:layout_height="60dip"
|
||||
a:layout_gravity="center"
|
||||
a:background="@color/translucent"
|
||||
a:layout_marginLeft="80dip"
|
||||
a:layout_marginRight="80dip"
|
||||
a:layout_marginStart="80dip"
|
||||
a:layout_marginEnd="80dip"
|
||||
a:orientation="vertical"
|
||||
/>
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="20dip"
|
||||
android:paddingLeft="40dip"
|
||||
android:paddingRight="40dip"/>
|
||||
android:paddingStart="40dip"
|
||||
android:paddingEnd="40dip"/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_alignParentRight="true"
|
||||
a:layout_toRightOf="@+id/equalizer.frequency"
|
||||
a:layout_toEndOf="@+id/equalizer.frequency"
|
||||
/>
|
||||
|
||||
<SeekBar
|
||||
|
|
|
@ -29,10 +29,8 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:layout_alignParentBottom="true"
|
||||
a:layout_marginStart="10dp"
|
||||
a:layout_marginLeft="10dp"
|
||||
a:layout_marginTop="10dp"
|
||||
a:layout_marginEnd="10dp"
|
||||
a:layout_marginRight="10dp"
|
||||
a:layout_marginBottom="10dp"
|
||||
a:drawableStart="?attr/filepicker_create_new_folder"
|
||||
a:drawableLeft="?attr/filepicker_create_new_folder"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:layout_marginStart="20dp"
|
||||
a:layout_marginLeft="20dp"
|
||||
a:gravity="center_vertical"
|
||||
a:text=""
|
||||
a:textSize="18sp" />
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingLeft="3dip"
|
||||
a:paddingRight="3dip"
|
||||
a:paddingStart="3dip"
|
||||
a:paddingEnd="3dip"
|
||||
a:minHeight="50dip"/>
|
|
@ -14,8 +14,8 @@
|
|||
a:textColor="#ffffffff"
|
||||
a:shadowColor="#bb000000"
|
||||
a:shadowRadius="2.75"
|
||||
a:paddingLeft="32dp"
|
||||
a:paddingRight="32dp"
|
||||
a:paddingStart="32dp"
|
||||
a:paddingEnd="32dp"
|
||||
a:paddingBottom="12dp"
|
||||
/>
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
a:gravity="center_horizontal"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:paddingLeft="10dip"
|
||||
a:paddingRight="10dip"
|
||||
a:paddingStart="10dip"
|
||||
a:paddingEnd="10dip"
|
||||
a:paddingTop="10dip"
|
||||
a:paddingBottom="4dip"
|
||||
/>
|
||||
|
@ -40,8 +40,8 @@
|
|||
a:gravity="center_horizontal"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:paddingLeft="10dip"
|
||||
a:paddingRight="10dip"
|
||||
a:paddingStart="10dip"
|
||||
a:paddingEnd="10dip"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
|
@ -51,8 +51,8 @@
|
|||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:paddingTop="32dip"
|
||||
a:paddingLeft="10dip"
|
||||
a:paddingRight="10dip"
|
||||
a:paddingStart="10dip"
|
||||
a:paddingEnd="10dip"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<LinearLayout a:id="@+id/main_select_server"
|
||||
a:orientation="horizontal" a:paddingTop="2dip" a:paddingBottom="2dip"
|
||||
a:paddingLeft="10dp" a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:paddingStart="10dp" a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:minHeight="?android:attr/listPreferredItemHeight">
|
||||
|
||||
<ImageView a:layout_width="wrap_content" a:layout_height="wrap_content"
|
||||
|
@ -19,7 +19,7 @@
|
|||
a:id="@+id/main.select_server_1"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="10dip"
|
||||
a:layout_marginStart="10dip"
|
||||
a:layout_marginTop="6dip"
|
||||
a:text="@string/main.select_server"
|
||||
a:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
@ -28,7 +28,7 @@
|
|||
a:id="@+id/main.select_server_2"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="10dip"
|
||||
a:layout_marginStart="10dip"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -37,95 +37,95 @@
|
|||
<TextView a:id="@+id/main_music" a:text="@string/main.music"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
|
||||
a:gravity="center_vertical" a:paddingLeft="6dp" a:textAllCaps="true"
|
||||
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
|
||||
a:textStyle="bold" />
|
||||
|
||||
<TextView a:id="@+id/main_artists_button" a:text="@string/main.artists_title"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_button" a:text="@string/main.albums_title"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_genres_button" a:text="@string/main.genres_title"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_songs" a:text="@string/main.songs_title"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
|
||||
a:gravity="center_vertical" a:paddingLeft="6dp" a:textAllCaps="true"
|
||||
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
|
||||
a:textStyle="bold" />
|
||||
|
||||
<TextView a:id="@+id/main_songs_button" a:text="@string/main.songs_random"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_songs_starred" a:text="@string/main.songs_starred"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_albums" a:text="@string/main.albums_title"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
|
||||
a:gravity="center_vertical" a:paddingLeft="6dp" a:textAllCaps="true"
|
||||
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
|
||||
a:textStyle="bold" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_newest" a:text="@string/main.albums_newest"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_recent" a:text="@string/main.albums_recent"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_frequent" a:text="@string/main.albums_frequent"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_highest" a:text="@string/main.albums_highest"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_random" a:text="@string/main.albums_random"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
|
||||
a:paddingLeft="6dip" a:paddingRight="6dip" a:minHeight="40dip" />
|
||||
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_starred" a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content" a:gravity="center_vertical"
|
||||
a:minHeight="40dip" a:paddingLeft="6dip" a:paddingRight="6dip"
|
||||
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
|
||||
a:text="@string/main.albums_starred" a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_alphaByName" a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content" a:gravity="center_vertical"
|
||||
a:minHeight="40dip" a:paddingLeft="6dip" a:paddingRight="6dip"
|
||||
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
|
||||
a:text="@string/main.albums_alphaByName" a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView a:id="@+id/main_albums_alphaByArtist" a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content" a:gravity="center_vertical"
|
||||
a:minHeight="40dip" a:paddingLeft="6dip" a:paddingRight="6dip"
|
||||
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
|
||||
a:text="@string/main.albums_alphaByArtist" a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView a:id="@+id/main_videos_title" a:text="@string/main.videos"
|
||||
a:layout_width="fill_parent" a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
|
||||
a:gravity="center_vertical" a:paddingLeft="6dp" a:textAllCaps="true"
|
||||
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
|
||||
a:textStyle="bold" />
|
||||
|
||||
<TextView a:id="@+id/main_videos" a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content" a:gravity="center_vertical"
|
||||
a:minHeight="40dip" a:paddingLeft="6dip" a:paddingRight="6dip"
|
||||
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
|
||||
a:text="@string/main.videos" a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:orientation="horizontal"
|
||||
a:layout_marginLeft="12dp"
|
||||
a:layout_marginRight="12dp" >
|
||||
a:layout_marginStart="12dp"
|
||||
a:layout_marginEnd="12dp" >
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/button_shuffle"
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
a:layout_height="match_parent"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingStart="16dp"
|
||||
a:paddingLeft="16dp"
|
||||
a:text="@string/common.appname"
|
||||
a:textAppearance="@style/TextAppearance.AppCompat.Title" />
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
android:id="@+id/now_playing_image"
|
||||
android:layout_width="64.0dip"
|
||||
android:layout_height="64.0dip"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="6dp" />
|
||||
|
@ -30,14 +29,13 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1.0"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="11.0dip"
|
||||
android:paddingStart="11.0dip">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/now_playing_trackname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:layout_gravity="start"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
|
@ -47,7 +45,7 @@
|
|||
android:id="@+id/now_playing_artist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:layout_gravity="start"
|
||||
android:ellipsize="end"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
|
@ -58,9 +56,9 @@
|
|||
android:id="@+id/now_playing_control_play"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center|right"
|
||||
android:layout_gravity="center|end"
|
||||
android:layout_marginTop="2dip"
|
||||
android:layout_marginRight="16dip"
|
||||
android:layout_marginEnd="16dip"
|
||||
android:layout_weight="0.0"
|
||||
android:focusable="false"
|
||||
android:scaleType="fitCenter"
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="10dp"
|
||||
a:layout_marginLeft="12dp"
|
||||
a:layout_marginRight="12dp" >
|
||||
a:layout_marginStart="12dp"
|
||||
a:layout_marginEnd="12dp" >
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="wrap_content"
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:orientation="vertical"
|
||||
a:layout_marginTop="10dp"
|
||||
a:layout_marginLeft="12dp"
|
||||
a:layout_marginRight="12dp" >
|
||||
a:layout_marginStart="12dp"
|
||||
a:layout_marginEnd="12dp" >
|
||||
|
||||
<SeekBar
|
||||
a:id="@+id/current_playing_progress_bar"
|
||||
|
@ -22,7 +22,7 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_alignParentLeft="true"
|
||||
a:layout_marginLeft="12dip"
|
||||
a:layout_marginStart="12dip"
|
||||
a:text="@string/util.no_time"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_alignParentRight="true"
|
||||
a:layout_marginRight="12dip"
|
||||
a:layout_marginEnd="12dip"
|
||||
a:text="@string/util.no_time"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
android:layout_weight="1"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:gravity="left|center_vertical"
|
||||
android:paddingLeft="6dip"
|
||||
android:paddingRight="6dip"
|
||||
android:paddingStart="6dip"
|
||||
android:paddingEnd="6dip"
|
||||
android:minHeight="50dip"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -24,7 +24,7 @@
|
|||
a:textStyle="bold"
|
||||
a:background="#ff555555"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingLeft="4dp"/>
|
||||
a:paddingStart="4dp"/>
|
||||
|
||||
<TextView
|
||||
a:id="@+id/search_albums"
|
||||
|
@ -36,7 +36,7 @@
|
|||
a:textStyle="bold"
|
||||
a:background="#ff555555"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingLeft="4dp"/>
|
||||
a:paddingStart="4dp"/>
|
||||
|
||||
<TextView
|
||||
a:id="@+id/search_songs"
|
||||
|
@ -48,7 +48,7 @@
|
|||
a:textStyle="bold"
|
||||
a:background="#ff555555"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingLeft="4dp"/>
|
||||
a:paddingStart="4dp"/>
|
||||
|
||||
<TextView
|
||||
a:id="@+id/search_more_artists"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
a:layout_height="160dip"
|
||||
a:layout_alignParentLeft="true"
|
||||
a:layout_alignParentTop="true"
|
||||
a:layout_marginRight="10dip"
|
||||
a:layout_marginEnd="10dip"
|
||||
a:contentDescription="@null"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/unknown_album"/>
|
||||
|
@ -18,9 +18,9 @@
|
|||
a:id="@+id/select_album_title"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_toRightOf="@+id/select_album_art"
|
||||
a:layout_toEndOf="@+id/select_album_art"
|
||||
a:ellipsize="end"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:paddingTop="10dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
@ -30,9 +30,9 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_below="@+id/select_album_title"
|
||||
a:layout_toRightOf="@+id/select_album_art"
|
||||
a:layout_toEndOf="@+id/select_album_art"
|
||||
a:ellipsize="end"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
|
@ -41,9 +41,9 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_below="@+id/select_album_artist"
|
||||
a:layout_toRightOf="@+id/select_album_art"
|
||||
a:layout_toEndOf="@+id/select_album_art"
|
||||
a:ellipsize="end"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
|
@ -52,9 +52,9 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_below="@+id/select_album_genre"
|
||||
a:layout_toRightOf="@+id/select_album_art"
|
||||
a:layout_toEndOf="@+id/select_album_art"
|
||||
a:ellipsize="end"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
|
@ -63,9 +63,9 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_below="@+id/select_album_year"
|
||||
a:layout_toRightOf="@+id/select_album_art"
|
||||
a:layout_toEndOf="@+id/select_album_art"
|
||||
a:ellipsize="none"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
|
@ -74,9 +74,9 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_below="@+id/select_album_song_count"
|
||||
a:layout_toRightOf="@+id/select_album_art"
|
||||
a:layout_toEndOf="@+id/select_album_art"
|
||||
a:ellipsize="none"
|
||||
a:paddingRight="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
a:minHeight="?android:attr/listPreferredItemHeight"
|
||||
a:orientation="horizontal"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingLeft="6dp"
|
||||
a:paddingStart="6dp"
|
||||
a:paddingTop="2dip"
|
||||
a:background="?android:attr/selectableItemBackground"
|
||||
a:clickable="true"
|
||||
|
@ -27,7 +27,7 @@
|
|||
a:id="@+id/select_folder_title"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="10dip"
|
||||
a:layout_marginStart="10dip"
|
||||
a:layout_marginTop="6dip"
|
||||
a:text="@string/select_artist.folder"
|
||||
a:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
@ -36,7 +36,7 @@
|
|||
a:id="@+id/select_folder_name"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginLeft="10dip"
|
||||
a:layout_marginStart="10dip"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -110,7 +110,6 @@
|
|||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginLeft="5dp"
|
||||
a:text="@string/settings.title.allow_self_signed_certificate"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_ldap_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -121,9 +120,7 @@
|
|||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="8dp"
|
||||
a:layout_marginLeft="8dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:layout_marginRight="5dp"
|
||||
a:layout_marginBottom="8dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_ldap_title"
|
||||
|
@ -137,7 +134,6 @@
|
|||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginLeft="5dp"
|
||||
a:text="@string/settings.title.enable_ldap_users_support"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_ldap_description"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -149,7 +145,6 @@
|
|||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginLeft="5dp"
|
||||
a:text="@string/settings.summary.enable_ldap_users_support"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_jukebox"
|
||||
app:layout_constraintEnd_toStartOf="@id/edit_ldap"
|
||||
|
@ -161,8 +156,6 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:layout_marginRight="5dp"
|
||||
a:layout_marginLeft="8dp"
|
||||
a:layout_marginStart="8dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_ldap_description"
|
||||
|
@ -176,7 +169,6 @@
|
|||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginLeft="5dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:text="@string/jukebox.is_default"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -187,10 +179,8 @@
|
|||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="8dp"
|
||||
a:layout_marginLeft="8dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:layout_marginRight="5dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_jukebox_title"
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:textAppearance="?android:attr/textAppearanceListItem"
|
||||
a:paddingTop="10dp"
|
||||
a:layout_toRightOf="@id/server_image"
|
||||
a:layout_toEndOf="@id/server_image" />
|
||||
|
||||
<TextView
|
||||
|
@ -31,7 +30,6 @@
|
|||
a:textAppearance="?android:attr/textAppearanceSmall"
|
||||
a:layout_below="@id/server_name"
|
||||
a:paddingBottom="10dp"
|
||||
a:layout_toRightOf="@id/server_image"
|
||||
a:layout_toEndOf="@id/server_image" />
|
||||
|
||||
<ImageButton
|
||||
|
@ -43,7 +41,7 @@
|
|||
a:layout_centerVertical="true"
|
||||
a:layout_gravity="end"
|
||||
a:layout_marginEnd="15dp"
|
||||
a:layout_marginRight="15dp"
|
||||
|
||||
a:focusable="false"
|
||||
a:src="?attr/more_vert"
|
||||
a:padding="5dp" />
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:layout_weight="1"
|
||||
a:paddingLeft="6dip"
|
||||
a:paddingRight="6dip"
|
||||
a:paddingStart="6dip"
|
||||
a:paddingEnd="6dip"
|
||||
a:minHeight="44dip"
|
||||
a:orientation="vertical">
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
|||
a:layout_gravity="left|center_vertical"
|
||||
a:layout_weight="1"
|
||||
a:ellipsize="middle"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:layout_weight="1"
|
||||
a:layout_marginLeft="4dp"
|
||||
a:layout_marginStart="4dp"
|
||||
a:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -28,8 +28,8 @@
|
|||
a:layout_weight="1"
|
||||
a:drawablePadding="6dip"
|
||||
a:ellipsize="end"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingRight="2dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="2dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
|||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="right|center_vertical"
|
||||
a:drawablePadding="6dip"
|
||||
a:paddingRight="6dip"/>
|
||||
a:paddingEnd="6dip"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -55,7 +55,7 @@
|
|||
a:layout_gravity="left|center_vertical"
|
||||
a:layout_weight="1"
|
||||
a:ellipsize="middle"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
|
@ -64,8 +64,8 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="right|center_vertical"
|
||||
a:paddingLeft="3dip"
|
||||
a:paddingRight="9dip"
|
||||
a:paddingStart="3dip"
|
||||
a:paddingEnd="9dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
a:id="@+id/song_drag"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="fill_parent"
|
||||
a:paddingLeft="5dip"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingRight="0dip"
|
||||
a:paddingEnd="0dip"
|
||||
a:background="@android:color/transparent"
|
||||
a:focusable="false"
|
||||
|
@ -26,7 +24,7 @@
|
|||
a:layout_height="fill_parent"
|
||||
a:checkMark="?attr/button_check_custom"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingRight="4dip"/>
|
||||
a:paddingEnd="4dip"/>
|
||||
|
||||
<include layout="@layout/song_details" />
|
||||
|
||||
|
@ -82,7 +80,7 @@
|
|||
a:id="@+id/song_five_star_5"
|
||||
a:layout_width="10dip"
|
||||
a:layout_height="fill_parent"
|
||||
a:layout_marginRight="8dip"
|
||||
a:layout_marginEnd="8dip"
|
||||
a:background="@android:color/transparent"
|
||||
a:focusable="false"
|
||||
a:gravity="center_vertical"
|
||||
|
@ -98,7 +96,7 @@
|
|||
a:background="@android:color/transparent"
|
||||
a:focusable="false"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingRight="8dip"
|
||||
a:paddingEnd="8dip"
|
||||
a:src="?attr/star_hollow" />
|
||||
|
||||
</LinearLayout>
|
|
@ -44,7 +44,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:id="@+id/timeSpanSpinner"
|
||||
android:layout_alignBottom="@+id/timeSpanEditText"
|
||||
android:layout_toRightOf="@+id/timeSpanEditText"/>
|
||||
android:layout_toEndOf="@+id/timeSpanEditText"/>
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -12,7 +12,7 @@
|
|||
android:id="@+id/get_playlist_name_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:textSize="20sp"
|
||||
android:text="@string/common.name" />
|
||||
<EditText
|
||||
|
@ -21,7 +21,7 @@
|
|||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:hint="@string/common.name" />
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
|||
android:id="@+id/get_playlist_comment_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:textSize="20sp"
|
||||
android:text="@string/common.comment" />
|
||||
<EditText
|
||||
|
@ -43,7 +43,7 @@
|
|||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:hint="@string/common.comment" />
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
|||
android:id="@+id/get_playlist_public_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:textSize="20sp"
|
||||
android:text="@string/common.public" />
|
||||
<CheckBox
|
||||
|
@ -64,7 +64,7 @@
|
|||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:checked="false"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -19,8 +19,8 @@
|
|||
a:layout_gravity="left|center_vertical"
|
||||
a:layout_weight="1"
|
||||
a:ellipsize="end"
|
||||
a:paddingLeft="4dip"
|
||||
a:paddingRight="2dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="2dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
||||
|
@ -29,8 +29,8 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="right|center_vertical"
|
||||
a:paddingLeft="2dip"
|
||||
a:paddingRight="6dip"
|
||||
a:paddingStart="2dip"
|
||||
a:paddingEnd="6dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="fill_parent"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingLeft="1dip"
|
||||
a:paddingStart="1dip"
|
||||
a:visibility="gone" />
|
||||
|
||||
<include layout="@layout/video_details"
|
||||
|
@ -23,7 +23,7 @@
|
|||
a:background="@android:color/transparent"
|
||||
a:focusable="false"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingRight="8dip"
|
||||
a:paddingEnd="8dip"
|
||||
a:src="?attr/star_hollow" />
|
||||
|
||||
</LinearLayout>
|
|
@ -420,43 +420,36 @@
|
|||
<plurals name="select_album_n_songs">
|
||||
<item quantity="one">%d skladba</item>
|
||||
<item quantity="few">%d skladby</item>
|
||||
<item quantity="many">%d skladeb</item>
|
||||
<item quantity="other">%d skladeb</item>
|
||||
</plurals>
|
||||
<plurals name="select_album_n_songs_pinned">
|
||||
<item quantity="one">%d skladba vybrána pro připnutí.</item>
|
||||
<item quantity="few">%d skladby vybrány pro připnutí.</item>
|
||||
<item quantity="many">%d skladeb vybráno pro připnutí.</item>
|
||||
<item quantity="other">%d skladeb vybráno pro připnutí.</item>
|
||||
</plurals>
|
||||
<plurals name="select_album_n_songs_downloaded">
|
||||
<item quantity="one">%d skladba vybrána pro stažení.</item>
|
||||
<item quantity="few">%d skladby vybrány pro stažení.</item>
|
||||
<item quantity="many">%d skladeb vybráno pro stažení.</item>
|
||||
<item quantity="other">%d skladeb vybráno pro stažení.</item>
|
||||
</plurals>
|
||||
<plurals name="select_album_n_songs_unpinned">
|
||||
<item quantity="one">%d skladba vybrána pro odepnutí.</item>
|
||||
<item quantity="few">%d skladby vybrány pro odepnutí.</item>
|
||||
<item quantity="many">%d skladeb vybráno pro odepnutí.</item>
|
||||
<item quantity="other">%d skladeb vybráno pro odepnutí.</item>
|
||||
</plurals>
|
||||
<plurals name="select_album_n_songs_added">
|
||||
<item quantity="one">%d skladba přidána na konec fronty přehrávání.</item>
|
||||
<item quantity="few">%d skladyb přidány na konec fronty přehrávání.</item>
|
||||
<item quantity="many">%d skladeb přidáno na konec fronty přehrávání.</item>
|
||||
<item quantity="other">%d skladeb přidáno na konec fronty přehrávání.</item>
|
||||
</plurals>
|
||||
<plurals name="select_album_n_songs_play_next">
|
||||
<item quantity="one">%d skladba přidána za aktuální skladbu.</item>
|
||||
<item quantity="few">%d skladby přidány za aktuální skladbu.</item>
|
||||
<item quantity="many">%d skladeb přidáno za aktuální skladbu.</item>
|
||||
<item quantity="other">%d skladeb přidáno za aktuální skladbu.</item>
|
||||
</plurals>
|
||||
<plurals name="select_album_donate_dialog_n_trial_days_left">
|
||||
<item quantity="one">Zbývá %d den zkušební doby</item>
|
||||
<item quantity="few">Zbývají %d dny zkušební doby</item>
|
||||
<item quantity="many">Zbývá %d dní zkušební doby</item>
|
||||
<item quantity="other">Zbývá %d dní zkušební doby</item>
|
||||
</plurals>
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textAllCaps">true</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="android:paddingLeft">16dp</item>
|
||||
<item name="android:paddingStart">16dp</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="40dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x1"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x1"/>
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="40dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x1"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x1"
|
||||
tools:ignore="UnusedAttribute" />
|
|
@ -1,9 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="110dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x2"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x2"/>
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="110dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x2"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x2"
|
||||
tools:ignore="UnusedAttribute" />
|
Loading…
Reference in New Issue