Merge branch 'master' into dynamic_size_status_bars
This commit is contained in:
commit
a0c57357e3
32 changed files with 647 additions and 34 deletions
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.kabouzeid.gramophone"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.kabouzeid.gramophone">
|
||||
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
|
@ -173,6 +173,10 @@
|
|||
<activity
|
||||
android:name=".ui.activities.bugreport.BugReportActivity"
|
||||
android:label="@string/report_an_issue" />
|
||||
<activity
|
||||
android:name=".appshortcuts.AppShortcutLauncherActivity"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:launchMode="singleInstance"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -25,6 +25,20 @@
|
|||
|
||||
<p>You can view the changelog dialog again at any time from the <i>about</i> section.</p>
|
||||
|
||||
<h3>Version 0.15.0 BETA 1</h3>
|
||||
|
||||
<ol>
|
||||
<li><b>NEW:</b> App Shortcuts (Android Nougat only)</li>
|
||||
</ol>
|
||||
|
||||
<h3>Version 0.14.1</h3>
|
||||
|
||||
<ol>
|
||||
<li><b>FIX:</b> Notification won't disappear.</li>
|
||||
<li><b>IMPROVEMENT:</b> Updated libraries.</li>
|
||||
<li><b>IMPROVEMENT:</b> Synced translations.</li>
|
||||
</ol>
|
||||
|
||||
<h3>Version 0.14.0</h3>
|
||||
|
||||
<ol>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,33 @@
|
|||
package com.kabouzeid.gramophone;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.Build;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.core.CrashlyticsCore;
|
||||
import com.kabouzeid.gramophone.appshortcuts.DynamicShortcutManager;
|
||||
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class App extends Application {
|
||||
public static final String GOOGLE_PLAY_LICENSE_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjMeADN5Ffnt/ml5SYxNPCn8kGcOYGpHEfNSCts99vVxqmCn6C01E94c17j7rUK2aeHur5uxphZylzopPlQ8P8l1fqty0GPUNRSo18FCJzfGH8HZAwZYOcnRFPaXdaq3InyFJhBiODh2oeAcVK/idH6QraQ4r9HIlzigAg6lgwzxl2wJKDh7X/GMdDntCyzDh8xDQ0wIawFgvgojHwqh2Ci8Gnq6EYRwPA9yHiIIksT8Q30QyM5ewl5QcnWepsls7enNqeHarhpmSibRUDgCsxHoOpny7SyuvZvUI3wuLckDR0ds9hrt614scHHqDOBp/qWCZiAgOPVAEQcURbV09qQIDAQAB";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
// Set up Crashlytics, disabled for debug builds
|
||||
Crashlytics crashlyticsKit = new Crashlytics.Builder()
|
||||
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
|
||||
.build();
|
||||
Fabric.with(this, crashlyticsKit);
|
||||
|
||||
//Set up dynamic shortcuts
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
new DynamicShortcutManager(this).initDynamicShortcuts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
package com.kabouzeid.gramophone.appshortcuts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.kabouzeid.appthemehelper.ThemeStore;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||
public final class AppShortcutIconGenerator {
|
||||
public static Icon generateThemedIcon(Context context, int iconId) {
|
||||
if (PreferenceUtil.getInstance(context).coloredAppShortcuts()){
|
||||
return generateUserThemedIcon(context, iconId);
|
||||
} else {
|
||||
return generateDefaultThemedIcon(context, iconId);
|
||||
}
|
||||
}
|
||||
|
||||
private static Icon generateDefaultThemedIcon(Context context, int iconId) {
|
||||
//Return an Icon of iconId with default colors
|
||||
return generateThemedIcon(context, iconId,
|
||||
context.getColor(R.color.app_shortcut_default_foreground),
|
||||
context.getColor(R.color.app_shortcut_default_background)
|
||||
);
|
||||
}
|
||||
|
||||
private static Icon generateUserThemedIcon(Context context, int iconId) {
|
||||
//Get background color from context's theme
|
||||
final TypedValue typedColorBackground = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.colorBackground, typedColorBackground, true);
|
||||
|
||||
//Return an Icon of iconId with those colors
|
||||
return generateThemedIcon(context, iconId,
|
||||
ThemeStore.primaryColor(context),
|
||||
typedColorBackground.data
|
||||
);
|
||||
}
|
||||
|
||||
private static Icon generateThemedIcon(Context context, int iconId, int foregroundColor, int backgroundColor) {
|
||||
//Get and tint foreground and background drawables
|
||||
Drawable vectorDrawable = Util.getTintedVectorDrawable(context, iconId, foregroundColor);
|
||||
Drawable backgroundDrawable = Util.getTintedVectorDrawable(context, R.drawable.ic_app_shortcut_background, backgroundColor);
|
||||
|
||||
//Squash the two drawables together
|
||||
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{backgroundDrawable, vectorDrawable});
|
||||
|
||||
//Return as an Icon
|
||||
return Icon.createWithBitmap(drawableToBitmap(layerDrawable));
|
||||
}
|
||||
|
||||
private static Bitmap drawableToBitmap(Drawable drawable) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package com.kabouzeid.gramophone.appshortcuts;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.IntDef;
|
||||
|
||||
import com.kabouzeid.gramophone.appshortcuts.shortcuttype.LastAddedShortcutType;
|
||||
import com.kabouzeid.gramophone.appshortcuts.shortcuttype.ShuffleAllShortcutType;
|
||||
import com.kabouzeid.gramophone.appshortcuts.shortcuttype.TopTracksShortcutType;
|
||||
import com.kabouzeid.gramophone.loader.LastAddedLoader;
|
||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||
import com.kabouzeid.gramophone.loader.TopAndRecentlyPlayedTracksLoader;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.service.MusicService;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
public class AppShortcutLauncherActivity extends Activity {
|
||||
public static final String KEY_SHORTCUT_TYPE = "com.kabouzeid.gramophone.appshortcuts.ShortcutType";
|
||||
|
||||
public static final int SHORTCUT_TYPE_SHUFFLE_ALL = 0;
|
||||
public static final int SHORTCUT_TYPE_TOP_TRACKS = 1;
|
||||
public static final int SHORTCUT_TYPE_LAST_ADDED = 2;
|
||||
public static final int SHORTCUT_TYPE_NONE = 3;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@ShortcutType
|
||||
int shortcutType = SHORTCUT_TYPE_NONE;
|
||||
|
||||
//Set shortcutType from the intent extras
|
||||
Bundle extras = getIntent().getExtras();
|
||||
if (extras != null) {
|
||||
//noinspection WrongConstant
|
||||
shortcutType = extras.getInt(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE);
|
||||
}
|
||||
|
||||
switch (shortcutType) {
|
||||
case SHORTCUT_TYPE_SHUFFLE_ALL:
|
||||
startServiceWithSongs(MusicService.SHUFFLE_MODE_SHUFFLE,
|
||||
SongLoader.getAllSongs(getApplicationContext()));
|
||||
DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.getId());
|
||||
break;
|
||||
case SHORTCUT_TYPE_TOP_TRACKS:
|
||||
startServiceWithSongs(MusicService.SHUFFLE_MODE_NONE,
|
||||
TopAndRecentlyPlayedTracksLoader.getTopTracks(getApplicationContext()));
|
||||
DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.getId());
|
||||
break;
|
||||
case SHORTCUT_TYPE_LAST_ADDED:
|
||||
startServiceWithSongs(MusicService.SHUFFLE_MODE_NONE,
|
||||
LastAddedLoader.getLastAddedSongs(getApplicationContext()));
|
||||
DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.getId());
|
||||
break;
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
private void startServiceWithSongs(int shuffleMode, ArrayList<Song> songs) {
|
||||
Intent intent = new Intent(this, MusicService.class);
|
||||
intent.setAction(MusicService.ACTION_PLAY);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelableArrayList(MusicService.INTENT_EXTRA_SONGS, songs);
|
||||
bundle.putInt(MusicService.INTENT_EXTRA_SHUFFLE_MODE, shuffleMode);
|
||||
|
||||
intent.putExtras(bundle);
|
||||
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({SHORTCUT_TYPE_SHUFFLE_ALL, SHORTCUT_TYPE_TOP_TRACKS, SHORTCUT_TYPE_LAST_ADDED, SHORTCUT_TYPE_NONE})
|
||||
public @interface ShortcutType {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package com.kabouzeid.gramophone.appshortcuts;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
|
||||
import com.kabouzeid.gramophone.appshortcuts.shortcuttype.LastAddedShortcutType;
|
||||
import com.kabouzeid.gramophone.appshortcuts.shortcuttype.ShuffleAllShortcutType;
|
||||
import com.kabouzeid.gramophone.appshortcuts.shortcuttype.TopTracksShortcutType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
public class DynamicShortcutManager {
|
||||
|
||||
private Context context;
|
||||
private ShortcutManager shortcutManager;
|
||||
|
||||
public DynamicShortcutManager(Context context) {
|
||||
this.context = context;
|
||||
shortcutManager = this.context.getSystemService(ShortcutManager.class);
|
||||
}
|
||||
|
||||
public static ShortcutInfo createShortcut(Context context, String id, String shortLabel, String longLabel, Icon icon, Intent intent) {
|
||||
return new ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(shortLabel)
|
||||
.setLongLabel(longLabel)
|
||||
.setIcon(icon)
|
||||
.setIntent(intent)
|
||||
.build();
|
||||
}
|
||||
|
||||
public void initDynamicShortcuts() {
|
||||
if (shortcutManager.getDynamicShortcuts().size() == 0) {
|
||||
shortcutManager.setDynamicShortcuts(getDefaultShortcuts());
|
||||
}
|
||||
}
|
||||
|
||||
public void updateDynamicShortcuts() {
|
||||
shortcutManager.updateShortcuts(getDefaultShortcuts());
|
||||
}
|
||||
|
||||
public List<ShortcutInfo> getDefaultShortcuts() {
|
||||
return (Arrays.asList(
|
||||
new ShuffleAllShortcutType(context).getShortcutInfo(),
|
||||
new TopTracksShortcutType(context).getShortcutInfo(),
|
||||
new LastAddedShortcutType(context).getShortcutInfo()
|
||||
));
|
||||
}
|
||||
|
||||
public static void reportShortcutUsed(Context context, String shortcutId){
|
||||
context.getSystemService(ShortcutManager.class).reportShortcutUsed(shortcutId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.kabouzeid.gramophone.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.kabouzeid.gramophone.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
@TargetApi(25)
|
||||
public abstract class BaseShortcutType {
|
||||
|
||||
static final String ID_PREFIX = "com.kabouzeid.gramophone.appshortcuts.id.";
|
||||
|
||||
Context context;
|
||||
|
||||
public BaseShortcutType(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
abstract ShortcutInfo getShortcutInfo();
|
||||
|
||||
static public String getId(){
|
||||
return ID_PREFIX + "invalid";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an Intent that will launch MainActivtiy and immediately play {@param songs} in either shuffle or normal mode
|
||||
*
|
||||
* @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
|
||||
* @return
|
||||
*/
|
||||
Intent getPlaySongsIntent(@AppShortcutLauncherActivity.ShortcutType int shortcutType) {
|
||||
Intent intent = new Intent(context, AppShortcutLauncherActivity.class);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
|
||||
Bundle b = new Bundle();
|
||||
b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType);
|
||||
|
||||
intent.putExtras(b);
|
||||
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.kabouzeid.gramophone.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.appshortcuts.AppShortcutIconGenerator;
|
||||
import com.kabouzeid.gramophone.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
@TargetApi(25)
|
||||
public final class LastAddedShortcutType extends BaseShortcutType {
|
||||
public LastAddedShortcutType(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ShortcutInfo getShortcutInfo() {
|
||||
return new ShortcutInfo.Builder(context, getId())
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_last_added_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_last_added_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_last_added))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_LAST_ADDED))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static String getId(){
|
||||
return ID_PREFIX + "last_added";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.kabouzeid.gramophone.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.appshortcuts.AppShortcutIconGenerator;
|
||||
import com.kabouzeid.gramophone.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
@TargetApi(25)
|
||||
public final class ShuffleAllShortcutType extends BaseShortcutType {
|
||||
public ShuffleAllShortcutType(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ShortcutInfo getShortcutInfo() {
|
||||
return new ShortcutInfo.Builder(context, getId())
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_shuffle_all_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_shuffle_all))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static String getId() {
|
||||
return ID_PREFIX + "shuffle_all";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.kabouzeid.gramophone.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.appshortcuts.AppShortcutIconGenerator;
|
||||
import com.kabouzeid.gramophone.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
@TargetApi(25)
|
||||
public final class TopTracksShortcutType extends BaseShortcutType {
|
||||
public TopTracksShortcutType(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ShortcutInfo getShortcutInfo() {
|
||||
return new ShortcutInfo.Builder(context, getId())
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_top_tracks_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_top_tracks_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_top_tracks))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_TOP_TRACKS))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static String getId() {
|
||||
return ID_PREFIX + "top_tracks";
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@ import android.provider.MediaStore;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.media.MediaMetadataCompat;
|
||||
import android.support.v4.media.session.MediaButtonReceiver;
|
||||
import android.support.v4.media.session.MediaSessionCompat;
|
||||
import android.support.v4.media.session.PlaybackStateCompat;
|
||||
import android.widget.Toast;
|
||||
|
|
@ -62,6 +61,7 @@ import com.kabouzeid.gramophone.util.Util;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid), Andrew Neal
|
||||
|
|
@ -79,6 +79,8 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
public static final String ACTION_SKIP = PHONOGRAPH_PACKAGE_NAME + ".skip";
|
||||
public static final String ACTION_REWIND = PHONOGRAPH_PACKAGE_NAME + ".rewind";
|
||||
public static final String ACTION_QUIT = PHONOGRAPH_PACKAGE_NAME + ".quitservice";
|
||||
public static final String INTENT_EXTRA_SONGS = PHONOGRAPH_PACKAGE_NAME + ".intentextra.songs";
|
||||
public static final String INTENT_EXTRA_SHUFFLE_MODE = PHONOGRAPH_PACKAGE_NAME + ".intentextra.shufflemode";
|
||||
|
||||
public static final String APP_WIDGET_UPDATE = PHONOGRAPH_PACKAGE_NAME + ".appwidgetupdate";
|
||||
public static final String EXTRA_APP_WIDGET_NAME = PHONOGRAPH_PACKAGE_NAME + "app_widget_name";
|
||||
|
|
@ -295,6 +297,20 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
pause();
|
||||
break;
|
||||
case ACTION_PLAY:
|
||||
ArrayList<Song> songs = intent.getParcelableArrayListExtra(INTENT_EXTRA_SONGS);
|
||||
if (songs != null) {
|
||||
int shuffleMode = intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode());
|
||||
if (intent.hasExtra(INTENT_EXTRA_SHUFFLE_MODE) && intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, 0) == SHUFFLE_MODE_SHUFFLE) {
|
||||
int startPosition = 0;
|
||||
if (!songs.isEmpty()) {
|
||||
startPosition = new Random().nextInt(songs.size());
|
||||
}
|
||||
openQueue(songs, startPosition, false);
|
||||
setShuffleMode(shuffleMode);
|
||||
} else {
|
||||
openQueue(songs, 0, false);
|
||||
}
|
||||
}
|
||||
play();
|
||||
break;
|
||||
case ACTION_REWIND:
|
||||
|
|
@ -522,9 +538,29 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
return (getAudioManager().requestAudioFocus(audioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
}
|
||||
|
||||
private void updateMediaSession() {
|
||||
private void updateNotification() {
|
||||
if (getCurrentSong().id != -1) {
|
||||
playingNotification.update();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMediaSessionPlaybackState() {
|
||||
mediaSession.setPlaybackState(
|
||||
new PlaybackStateCompat.Builder()
|
||||
.setActions(MEDIA_SESSION_ACTIONS)
|
||||
.setState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED,
|
||||
getPosition(), 1)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void updateMediaSessionMetaData() {
|
||||
final Song song = getCurrentSong();
|
||||
|
||||
if (song.id == -1) {
|
||||
mediaSession.setMetadata(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final MediaMetadataCompat.Builder metaData = new MediaMetadataCompat.Builder()
|
||||
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, song.artistName)
|
||||
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, song.artistName)
|
||||
|
|
@ -568,7 +604,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
} else {
|
||||
mediaSession.setMetadata(metaData.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Bitmap copy(Bitmap bitmap) {
|
||||
|
|
@ -985,22 +1020,17 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
private void handleChangeInternal(@NonNull final String what) {
|
||||
switch (what) {
|
||||
case PLAY_STATE_CHANGED:
|
||||
updateNotification();
|
||||
updateMediaSessionPlaybackState();
|
||||
final boolean isPlaying = isPlaying();
|
||||
playingNotification.update();
|
||||
mediaSession.setPlaybackState(
|
||||
new PlaybackStateCompat.Builder()
|
||||
.setActions(MEDIA_SESSION_ACTIONS)
|
||||
.setState(isPlaying ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED,
|
||||
getPosition(), 1)
|
||||
.build());
|
||||
if (!isPlaying && getSongProgressMillis() > 0) {
|
||||
savePositionInTrack();
|
||||
}
|
||||
songPlayCountHelper.notifyPlayStateChanged(isPlaying);
|
||||
break;
|
||||
case META_CHANGED:
|
||||
playingNotification.update();
|
||||
updateMediaSession();
|
||||
updateNotification();
|
||||
updateMediaSessionMetaData();
|
||||
savePosition();
|
||||
savePositionInTrack();
|
||||
final Song currentSong = getCurrentSong();
|
||||
|
|
@ -1011,12 +1041,12 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
songPlayCountHelper.notifySongChanged(currentSong);
|
||||
break;
|
||||
case QUEUE_CHANGED:
|
||||
updateMediaSession();
|
||||
updateMediaSessionMetaData(); // because playing queue size might have changed
|
||||
saveState();
|
||||
if (playingQueue.size() > 0) {
|
||||
prepareNext();
|
||||
} else {
|
||||
quit();
|
||||
playingNotification.stop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1052,10 +1082,10 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
break;
|
||||
case PreferenceUtil.ALBUM_ART_ON_LOCKSCREEN:
|
||||
case PreferenceUtil.BLURRED_ALBUM_ART:
|
||||
updateMediaSession();
|
||||
updateMediaSessionMetaData();
|
||||
break;
|
||||
case PreferenceUtil.COLORED_NOTIFICATION:
|
||||
playingNotification.update();
|
||||
updateNotification();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import com.kabouzeid.gramophone.service.MusicService;
|
|||
*/
|
||||
|
||||
public interface PlayingNotification {
|
||||
int NOTIFICATION_ID = 1;
|
||||
|
||||
void init(MusicService service);
|
||||
|
||||
void update();
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public class PlayingNotificationImpl implements PlayingNotification {
|
|||
|
||||
if (stopped)
|
||||
return; // notification has been stopped before loading was finished
|
||||
service.startForeground(1, notification);
|
||||
service.startForeground(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
private void setBackgroundColor(int color) {
|
||||
|
|
|
|||
|
|
@ -157,9 +157,9 @@ public class PlayingNotificationImpl24 implements PlayingNotification {
|
|||
}
|
||||
|
||||
if (newNotifyMode == NOTIFY_MODE_FOREGROUND) {
|
||||
service.startForeground(1, notification);
|
||||
service.startForeground(NOTIFICATION_ID, notification);
|
||||
} else if (newNotifyMode == NOTIFY_MODE_BACKGROUND) {
|
||||
notificationManager.notify(1, notification);
|
||||
notificationManager.notify(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
notifyMode = newNotifyMode;
|
||||
|
|
@ -169,5 +169,6 @@ public class PlayingNotificationImpl24 implements PlayingNotification {
|
|||
public synchronized void stop() {
|
||||
stopped = true;
|
||||
service.stopForeground(true);
|
||||
notificationManager.cancel(NOTIFICATION_ID);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,6 +296,7 @@ public class MainActivity extends AbsSlidingMusicPanelActivity {
|
|||
} else {
|
||||
MusicPlayerRemote.openQueue(songs, 0, true);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
|
||||
if (uri != null && uri.toString().length() > 0) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.kabouzeid.appthemehelper.common.prefs.supportv7.ATEColorPreference;
|
|||
import com.kabouzeid.appthemehelper.common.prefs.supportv7.ATEPreferenceFragmentCompat;
|
||||
import com.kabouzeid.appthemehelper.util.ColorUtil;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.appshortcuts.DynamicShortcutManager;
|
||||
import com.kabouzeid.gramophone.preferences.NowPlayingScreenPreference;
|
||||
import com.kabouzeid.gramophone.preferences.NowPlayingScreenPreferenceDialog;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
||||
|
|
@ -82,6 +83,10 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
|||
.commit();
|
||||
break;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
new DynamicShortcutManager(this).updateDynamicShortcuts();
|
||||
}
|
||||
recreate();
|
||||
}
|
||||
|
||||
|
|
@ -175,6 +180,13 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
|||
ThemeStore.editTheme(getActivity())
|
||||
.activityTheme(PreferenceUtil.getThemeResFromPrefValue((String) o))
|
||||
.commit();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
//Set the new theme so that updateAppShortcuts can pull it
|
||||
getActivity().setTheme(PreferenceUtil.getThemeResFromPrefValue((String) o));
|
||||
new DynamicShortcutManager(getActivity()).updateDynamicShortcuts();
|
||||
}
|
||||
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -240,6 +252,28 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
|||
});
|
||||
}
|
||||
|
||||
TwoStatePreference colorAppShortcuts = (TwoStatePreference) findPreference("should_color_app_shortcuts");
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
||||
colorAppShortcuts.setEnabled(false);
|
||||
colorAppShortcuts.setSummary(R.string.pref_only_nougat_mr1);
|
||||
} else {
|
||||
colorAppShortcuts.setChecked(PreferenceUtil.getInstance(getActivity()).coloredAppShortcuts());
|
||||
colorAppShortcuts.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
//Save preference
|
||||
PreferenceUtil.getInstance(getActivity()).setColoredAppShortcuts((Boolean)newValue);
|
||||
|
||||
//Update app shortcuts
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
new DynamicShortcutManager(getActivity()).updateDynamicShortcuts();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Preference equalizer = findPreference("equalizer");
|
||||
if (!hasEqualizer()) {
|
||||
equalizer.setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -319,7 +319,6 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
try {
|
||||
return AudioFileIO.read(new File(song.data)).getTagOrCreateDefault().getFirst(FieldKey.LYRICS);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
cancel(false);
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -319,7 +319,6 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
try {
|
||||
return AudioFileIO.read(new File(song.data)).getTagOrCreateDefault().getFirst(FieldKey.LYRICS);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
cancel(false);
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public final class PreferenceUtil {
|
|||
public static final String FORCE_SQUARE_ALBUM_COVER = "force_square_album_art";
|
||||
|
||||
public static final String COLORED_NOTIFICATION = "colored_notification";
|
||||
public static final String COLORED_APP_SHORTCUTS = "colored_app_shortcuts";
|
||||
|
||||
public static final String AUDIO_DUCKING = "audio_ducking";
|
||||
public static final String GAPLESS_PLAYBACK = "gapless_playback";
|
||||
|
|
@ -148,6 +149,16 @@ public final class PreferenceUtil {
|
|||
return mPreferences.getBoolean(COLORED_NOTIFICATION, true);
|
||||
}
|
||||
|
||||
public void setColoredAppShortcuts(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(COLORED_APP_SHORTCUTS, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean coloredAppShortcuts() {
|
||||
return mPreferences.getBoolean(COLORED_APP_SHORTCUTS, true);
|
||||
}
|
||||
|
||||
public final boolean gaplessPlayback() {
|
||||
return mPreferences.getBoolean(GAPLESS_PLAYBACK, false);
|
||||
}
|
||||
|
|
|
|||
18
app/src/main/res/drawable/ic_app_shortcut_background.xml
Normal file
18
app/src/main/res/drawable/ic_app_shortcut_background.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="176dp"
|
||||
android:height="176dp"
|
||||
android:viewportHeight="176"
|
||||
android:viewportWidth="176">
|
||||
|
||||
<group
|
||||
android:pivotX="88"
|
||||
android:pivotY="88"
|
||||
android:scaleX="0.916"
|
||||
android:scaleY="0.916">
|
||||
<path
|
||||
android:name="ic_app_shortcut_background"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M 88 0 C 136.601057985 0 176 39.3989420149 176 88 C 176 136.601057985 136.601057985 176 88 176 C 39.3989420149 176 0 136.601057985 0 88 C 0 39.3989420149 39.3989420149 0 88 0 Z" />
|
||||
</group>
|
||||
</vector>
|
||||
20
app/src/main/res/drawable/ic_app_shortcut_last_added.xml
Normal file
20
app/src/main/res/drawable/ic_app_shortcut_last_added.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="176dp"
|
||||
android:height="176dp"
|
||||
android:viewportHeight="176"
|
||||
android:viewportWidth="176">
|
||||
|
||||
<group
|
||||
android:pivotX="88"
|
||||
android:pivotY="88"
|
||||
android:scaleX="0.916"
|
||||
android:scaleY="0.916"
|
||||
android:translateX="-8"
|
||||
android:translateY="-8">
|
||||
<path
|
||||
android:name="ic_app_shortcut_last_added_ic"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M124.35,92h-16.2v16.2h-8.1V92H83.85v-8.1h16.2V67.65h8.1v16.2h16.2M128.4,55.5H79.8a8.1,8.1,0,0,0-8.1,8.1v48.6a8.1,8.1,0,0,0,8.1,8.1h48.6a8.1,8.1,0,0,0,8.1-8.1V63.6a8.1,8.1,0,0,0-8.1-8.1M63.6,71.7H55.5v56.7a8.1,8.1,0,0,0,8.1,8.1h56.7v-8.1H63.6Z" />
|
||||
</group>
|
||||
</vector>
|
||||
20
app/src/main/res/drawable/ic_app_shortcut_shuffle_all.xml
Normal file
20
app/src/main/res/drawable/ic_app_shortcut_shuffle_all.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="176dp"
|
||||
android:height="176dp"
|
||||
android:viewportHeight="176"
|
||||
android:viewportWidth="176">
|
||||
|
||||
<group
|
||||
android:pivotX="88"
|
||||
android:pivotY="88"
|
||||
android:scaleX="0.916"
|
||||
android:scaleY="0.916"
|
||||
android:translateX="-8"
|
||||
android:translateY="-8">
|
||||
<path
|
||||
android:name="ic_app_shortcut_shuffle_ic"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M110.15,103l-7,7,15.65,15.65L108.5,136H136V108.5l-10.2,10.2L110.15,103M108.5,56l10.2,10.2L56,128.95l7,7L125.8,73.3,136,83.5V56M89,81.85,63.05,56l-7,7L81.85,88.9Z" />
|
||||
</group>
|
||||
</vector>
|
||||
20
app/src/main/res/drawable/ic_app_shortcut_top_tracks.xml
Normal file
20
app/src/main/res/drawable/ic_app_shortcut_top_tracks.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="176dp"
|
||||
android:height="176dp"
|
||||
android:viewportHeight="176"
|
||||
android:viewportWidth="176">
|
||||
|
||||
<group
|
||||
android:pivotX="88"
|
||||
android:pivotY="88"
|
||||
android:scaleX="0.916"
|
||||
android:scaleY="0.916"
|
||||
android:translateX="-8"
|
||||
android:translateY="-8">
|
||||
<path
|
||||
android:name="ic_app_shortcut_top_tracks_ic"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M113.7,69.45l10.13,10.13-21.59,21.59-17.7-17.7L51.75,116.31,58,122.55,84.54,96l17.7,17.7,27.88-27.83L140.25,96V69.45Z" />
|
||||
</group>
|
||||
</vector>
|
||||
|
|
@ -20,6 +20,9 @@
|
|||
<string name="action_search">搜索</string>
|
||||
<string name="action_play_next">作为下一首播放</string>
|
||||
<string name="action_play">播放</string>
|
||||
<string name="action_play_pause">播放/暂停</string>
|
||||
<string name="action_previous">上一首</string>
|
||||
<string name="action_next">下一首</string>
|
||||
<string name="action_add_to_playing_queue">加入播放队列</string>
|
||||
<string name="action_remove_from_playing_queue">从播放队列中移除</string>
|
||||
<string name="action_add_to_playlist">加入播放列表</string>
|
||||
|
|
@ -45,6 +48,7 @@
|
|||
<string name="year">年份</string>
|
||||
<string name="track">音轨</string>
|
||||
<string name="track_hint">"音轨(如用 2 表示第 2 首歌或用 3004 表示 CD3 里的第 4 首歌)"</string>
|
||||
<string name="lyrics">歌词</string>
|
||||
<string name="album_or_artist_empty">标题或艺术家名称为空</string>
|
||||
<string name="saving_changes">正在保存更改…</string>
|
||||
<string name="saving_to_file">保存至文件...</string>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="twenty_percent_black_overlay">#34000000</color>
|
||||
|
||||
<color name="app_shortcut_default_foreground">#607d8b</color>
|
||||
<color name="app_shortcut_default_background">#f5f5f5</color>
|
||||
</resources>
|
||||
|
|
@ -39,4 +39,6 @@
|
|||
white-space: pre-wrap;
|
||||
}
|
||||
</string>
|
||||
|
||||
<string name="id_shortcuttype">com.kabouzeid.gramophone.appshortcuts.ShortcutType</string>
|
||||
</resources>
|
||||
|
|
@ -119,6 +119,7 @@
|
|||
<string name="pref_header_images">Images</string>
|
||||
<string name="pref_header_lockscreen">Lockscreen</string>
|
||||
<string name="pref_title_navigation_bar">Colored navigation bar</string>
|
||||
<string name="pref_title_app_shortcuts">Colored app shortcuts</string>
|
||||
<string name="pref_title_set_default_start_page">Start page</string>
|
||||
<string name="pref_title_album_art_on_lockscreen">Show album cover</string>
|
||||
<string name="pref_title_auto_download_artist_images">Auto download artist images</string>
|
||||
|
|
@ -158,6 +159,7 @@
|
|||
<string name="playlist_name_empty">Playlist name</string>
|
||||
<string name="song">Song</string>
|
||||
<string name="pref_only_lollipop">"Only available on Lollipop."</string>
|
||||
<string name="pref_only_nougat_mr1">"Only available on Nougat 7.1."</string>
|
||||
<string name="pref_summary_album_art_on_lockscreen">Uses the current songs album cover as lockscreen wallpaper.</string>
|
||||
<string name="pref_summary_blurred_album_art">Blurs the album cover on the lockscreen. Can cause problems with third party apps and widgets.</string>
|
||||
<string name="pref_summary_colored_notification">"Colors the notification in the album cover\u2019s vibrant color."</string>
|
||||
|
|
@ -171,6 +173,7 @@
|
|||
<string name="pref_summary_ignore_media_store_artwork">Can increase the album cover quality but causes slower image loading times. Only enable this if you have problems with low resolution artworks.</string>
|
||||
<string name="pref_summary_colored_playback_controls_now_playing">Colors play/pause, shuffle and repeat as well as the progress slider in the album cover\u2019s vibrant color.</string>
|
||||
<string name="pref_summary_colored_navigation_bar">Colors the navigation bar in the primary color.</string>
|
||||
<string name="pref_summary_colored_app_shortcuts">Colors the app shortcuts in the primary color.</string>
|
||||
<string name="pref_summary_audio_ducking">Notifications, navigation etc.</string>
|
||||
<string name="could_not_download_album_cover">"Couldn\u2019t download a matching album cover."</string>
|
||||
<string name="search_hint">Search your library…</string>
|
||||
|
|
@ -275,4 +278,14 @@
|
|||
<string name="copied_device_info_to_clipboard">Copied device info to clipboard.</string>
|
||||
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
|
||||
<string name="you_will_be_forwarded_to_the_issue_tracker_website">You will be forwarded to the issue tracker website.</string>
|
||||
|
||||
<!-- App Shortcuts -->
|
||||
<string name="app_shortcut_shuffle_all_long">@string/action_shuffle_all</string>
|
||||
<string name="app_shortcut_shuffle_all_short">Shuffle</string>
|
||||
|
||||
<string name="app_shortcut_top_tracks_long">@string/my_top_tracks</string>
|
||||
<string name="app_shortcut_top_tracks_short">Top Tracks</string>
|
||||
|
||||
<string name="app_shortcut_last_added_long">@string/last_added</string>
|
||||
<string name="app_shortcut_last_added_short">@string/last_added</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -48,4 +48,13 @@
|
|||
<item name="android:transitionName" tools:ignore="NewApi">toolbar</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Transparent" parent="android:Theme">
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:backgroundDimEnabled">false</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@
|
|||
android:summary="@string/pref_summary_colored_navigation_bar"
|
||||
android:title="@string/pref_title_navigation_bar" />
|
||||
|
||||
<com.kabouzeid.appthemehelper.common.prefs.supportv7.ATESwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="should_color_app_shortcuts"
|
||||
android:summary="@string/pref_summary_colored_app_shortcuts"
|
||||
android:title="@string/pref_title_app_shortcuts" />
|
||||
|
||||
</com.kabouzeid.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory>
|
||||
|
||||
</android.support.v7.preference.PreferenceScreen>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue