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,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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue