diff options
author | Renato Mangini <mangini@google.com> | 2014-10-02 10:46:11 -0700 |
---|---|---|
committer | Renato Mangini <mangini@google.com> | 2014-10-02 13:33:27 -0700 |
commit | 6768540171cd815002160bf76dcee1ae57b0fb28 (patch) | |
tree | c87b3c0f20f6f5de4b908ee1197341e9810829df /MusicDemo/src | |
parent | c9063ac9fb7a4f386d9ac69e0308b21199c7783e (diff) | |
download | demos-6768540171cd815002160bf76dcee1ae57b0fb28.tar.gz |
Updated MusicDemo sample.
Use material icons and colors;
Removed dependence on support libraries;
Added album art cache;
Bug: 17755718
Change-Id: I3085aa3e154393c3b0287783600f7187f7e42c7a
Diffstat (limited to 'MusicDemo/src')
20 files changed, 95 insertions, 91 deletions
diff --git a/MusicDemo/src/main/java/com/example/android/musicservicedemo/MediaNotification.java b/MusicDemo/src/main/java/com/example/android/musicservicedemo/MediaNotification.java index 33d14c1..59b526e 100644 --- a/MusicDemo/src/main/java/com/example/android/musicservicedemo/MediaNotification.java +++ b/MusicDemo/src/main/java/com/example/android/musicservicedemo/MediaNotification.java @@ -23,7 +23,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Bitmap; +import android.graphics.Color; import android.media.MediaDescription; import android.media.MediaMetadata; import android.media.session.MediaController; @@ -36,6 +41,7 @@ import com.example.android.musicservicedemo.utils.BitmapHelper; import com.example.android.musicservicedemo.utils.LogHelper; import java.io.IOException; +import java.util.LinkedHashMap; /** * Keeps track of a notification and updates it automatically for a given @@ -58,6 +64,7 @@ public class MediaNotification extends BroadcastReceiver { private MediaController mController; private MediaController.TransportControls mTransportControls; private final SparseArray<PendingIntent> mIntents = new SparseArray<PendingIntent>(); + private final LinkedHashMap<String, Bitmap> mAlbumArtCache; private PlaybackState mPlaybackState; private MediaMetadata mMetadata; @@ -67,6 +74,7 @@ public class MediaNotification extends BroadcastReceiver { private Notification.Action mPlayPauseAction; private String mCurrentAlbumArt; + private int mNotificationColor; private boolean mStarted = false; @@ -74,20 +82,49 @@ public class MediaNotification extends BroadcastReceiver { mService = service; updateSessionToken(); + // simple album art cache with up to 10 last accessed elements: + mAlbumArtCache = new LinkedHashMap<String, Bitmap>(10, 1f, true) { + @Override + protected boolean removeEldestEntry(Entry eldest) { + return size() > 10; + } + }; + + mNotificationColor = getNotificationColor(); + mNotificationManager = (NotificationManager) mService .getSystemService(Context.NOTIFICATION_SERVICE); String pkg = mService.getPackageName(); - mIntents.put(android.R.drawable.ic_media_pause, PendingIntent.getBroadcast(mService, 100, + mIntents.put(R.drawable.ic_pause_white_24dp, PendingIntent.getBroadcast(mService, 100, new Intent(ACTION_PAUSE).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT)); - mIntents.put(android.R.drawable.ic_media_play, PendingIntent.getBroadcast(mService, 100, + mIntents.put(R.drawable.ic_play_arrow_white_24dp, PendingIntent.getBroadcast(mService, 100, new Intent(ACTION_PLAY).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT)); - mIntents.put(android.R.drawable.ic_media_previous, PendingIntent.getBroadcast(mService, 100, + mIntents.put(R.drawable.ic_skip_previous_white_24dp, PendingIntent.getBroadcast(mService, 100, new Intent(ACTION_PREV).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT)); - mIntents.put(android.R.drawable.ic_media_next, PendingIntent.getBroadcast(mService, 100, + mIntents.put(R.drawable.ic_skip_next_white_24dp, PendingIntent.getBroadcast(mService, 100, new Intent(ACTION_NEXT).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT)); } + protected int getNotificationColor() { + int notificationColor = 0; + String packageName = mService.getPackageName(); + try { + Context packageContext = mService.createPackageContext(packageName, 0); + ApplicationInfo applicationInfo = + mService.getPackageManager().getApplicationInfo(packageName, 0); + packageContext.setTheme(applicationInfo.theme); + Resources.Theme theme = packageContext.getTheme(); + TypedArray ta = theme.obtainStyledAttributes( + new int[] {android.R.attr.colorPrimary}); + notificationColor = ta.getColor(0, Color.DKGRAY); + ta.recycle(); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return notificationColor; + } + /** * Posts the notification and starts tracking the session to keep it * updated. The notification will automatically be removed if the session is @@ -187,61 +224,64 @@ public class MediaNotification extends BroadcastReceiver { private void updateNotificationMetadata() { LogHelper.d(TAG, "updateNotificationMetadata. mMetadata=" + mMetadata); - if (mMetadata == null) { + if (mMetadata == null || mPlaybackState == null) { return; } updatePlayPauseAction(); - boolean firstRun = false; - - if (mNotificationBuilder == null) { - firstRun = true; - - mNotificationBuilder = new Notification.Builder(mService); + mNotificationBuilder = new Notification.Builder(mService); + int playPauseActionIndex = 0; + // If skip to previous action is enabled + if ((mPlaybackState.getActions() & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) { mNotificationBuilder - .addAction(android.R.drawable.ic_media_previous, + .addAction(R.drawable.ic_skip_previous_white_24dp, mService.getString(R.string.label_previous), - mIntents.get(android.R.drawable.ic_media_previous)) - .addAction(mPlayPauseAction) - .addAction(android.R.drawable.ic_media_next, - mService.getString(R.string.label_next), - mIntents.get(android.R.drawable.ic_media_next)) - .setStyle(new Notification.MediaStyle() - .setShowActionsInCompactView(1) // only show play/pause in compact view - .setMediaSession(mSessionToken)) - .setColor(android.R.attr.colorPrimaryDark) - .setSmallIcon(R.drawable.ic_notification) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .setUsesChronometer(true); + mIntents.get(R.drawable.ic_skip_previous_white_24dp)); + playPauseActionIndex = 1; + } + + mNotificationBuilder.addAction(mPlayPauseAction); + + // If skip to next action is enabled + if ((mPlaybackState.getActions() & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { + mNotificationBuilder.addAction(R.drawable.ic_skip_next_white_24dp, + mService.getString(R.string.label_next), + mIntents.get(R.drawable.ic_skip_next_white_24dp)); } MediaDescription description = mMetadata.getDescription(); Bitmap art = description.getIconBitmap(); + if (art == null && description.getIconUri() != null) { + // This sample assumes the iconUri will be a valid URL formatted String, but + // it can actually be any valid Android Uri formatted String. + // async fetch the album art icon + String artUrl = description.getIconUri().toString(); + art = mAlbumArtCache.get(artUrl); + if (art == null) { + fetchBitmapFromURLAsync(artUrl); + } else { + mNotificationBuilder.setLargeIcon(art); + } + } + mNotificationBuilder + .setStyle(new Notification.MediaStyle() + .setShowActionsInCompactView(playPauseActionIndex) // only show play/pause in compact view + .setMediaSession(mSessionToken)) + .setColor(mNotificationColor) + .setSmallIcon(R.drawable.ic_notification) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setOngoing(true) + .setUsesChronometer(true) .setContentTitle(description.getTitle()) .setContentText(description.getSubtitle()) .setLargeIcon(art); updateNotificationPlaybackState(); - if (firstRun) { - mService.startForeground(NOTIFICATION_ID, mNotificationBuilder.build()); - } else { - mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build()); - } - - if (art == null && description.getIconUri() != null) { - // This sample assumes the iconUri will be a valid URL formatted String, but - // it can actually be any valid Android Uri formatted String. - String albumUrl = description.getIconUri().toString(); - if (mCurrentAlbumArt == null || !mCurrentAlbumArt.equals(albumUrl)) { - mCurrentAlbumArt = albumUrl; - // async fetch the album art icon - getBitmapFromURLAsync(albumUrl); - } - } + mService.startForeground(NOTIFICATION_ID, mNotificationBuilder.build()); } private void updatePlayPauseAction() { @@ -250,10 +290,10 @@ public class MediaNotification extends BroadcastReceiver { int playPauseIcon; if (mPlaybackState.getState() == PlaybackState.STATE_PLAYING) { playPauseLabel = mService.getString(R.string.label_pause); - playPauseIcon = android.R.drawable.ic_media_pause; + playPauseIcon = R.drawable.ic_pause_white_24dp; } else { playPauseLabel = mService.getString(R.string.label_play); - playPauseIcon = android.R.drawable.ic_media_play; + playPauseIcon = R.drawable.ic_play_arrow_white_24dp; } if (mPlayPauseAction == null) { mPlayPauseAction = new Notification.Action(playPauseIcon, playPauseLabel, @@ -297,7 +337,7 @@ public class MediaNotification extends BroadcastReceiver { mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build()); } - public void getBitmapFromURLAsync(final String source) { + public void fetchBitmapFromURLAsync(final String source) { LogHelper.d(TAG, "getBitmapFromURLAsync: starting asynctask to fetch ", source); new AsyncTask() { @Override @@ -305,13 +345,12 @@ public class MediaNotification extends BroadcastReceiver { try { Bitmap bitmap = BitmapHelper.fetchAndRescaleBitmap(source, BitmapHelper.MEDIA_ART_BIG_WIDTH, BitmapHelper.MEDIA_ART_BIG_HEIGHT); + mAlbumArtCache.put(source, bitmap); if (mMetadata != null) { - MediaDescription currentDescription = mMetadata.getDescription(); + String currentSource = mMetadata.getDescription().getIconUri().toString(); // If the media is still the same, update the notification: - if (mNotificationBuilder != null && - currentDescription.getIconUri().toString().equals(source)) { + if (mNotificationBuilder != null && currentSource.equals(source)) { LogHelper.d(TAG, "getBitmapFromURLAsync: set bitmap to ", source); - mCurrentAlbumArt = source; mNotificationBuilder.setLargeIcon(bitmap); mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build()); diff --git a/MusicDemo/src/main/java/com/example/android/musicservicedemo/utils/BitmapHelper.java b/MusicDemo/src/main/java/com/example/android/musicservicedemo/utils/BitmapHelper.java index c743262..984de49 100644 --- a/MusicDemo/src/main/java/com/example/android/musicservicedemo/utils/BitmapHelper.java +++ b/MusicDemo/src/main/java/com/example/android/musicservicedemo/utils/BitmapHelper.java @@ -33,25 +33,6 @@ public class BitmapHelper { public static final int MEDIA_ART_BIG_WIDTH=128; public static final int MEDIA_ART_BIG_HEIGHT=128; - public static final Bitmap scaleBitmap(int targetW, int targetH, InputStream is) { - // Get the dimensions of the bitmap - BitmapFactory.Options bmOptions = new BitmapFactory.Options(); - bmOptions.inJustDecodeBounds = true; - BitmapFactory.decodeStream(is, null, bmOptions); - int actualW = bmOptions.outWidth; - int actualH = bmOptions.outHeight; - - // Determine how much to scale down the image - int scaleFactor = Math.min(actualW/targetW, actualH/targetH); - - // Decode the image file into a Bitmap sized to fill the View - bmOptions.inJustDecodeBounds = false; - bmOptions.inSampleSize = scaleFactor; - - Bitmap bitmap = BitmapFactory.decodeStream(is, null, bmOptions); - return bitmap; - } - public static final Bitmap scaleBitmap(int scaleFactor, InputStream is) { // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); diff --git a/MusicDemo/src/main/res/drawable-hdpi/ic_pause_white_24dp.png b/MusicDemo/src/main/res/drawable-hdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 0000000..b4bdbb5 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-hdpi/ic_pause_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png b/MusicDemo/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 0000000..164385d --- /dev/null +++ b/MusicDemo/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-hdpi/ic_shuffle_white_24dp.png b/MusicDemo/src/main/res/drawable-hdpi/ic_shuffle_white_24dp.png Binary files differnew file mode 100644 index 0000000..3eeb0ef --- /dev/null +++ b/MusicDemo/src/main/res/drawable-hdpi/ic_shuffle_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png b/MusicDemo/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png Binary files differnew file mode 100644 index 0000000..4eaf7ca --- /dev/null +++ b/MusicDemo/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png b/MusicDemo/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png Binary files differnew file mode 100644 index 0000000..e59dedb --- /dev/null +++ b/MusicDemo/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png b/MusicDemo/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 0000000..14b6d17 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png b/MusicDemo/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 0000000..a55d199 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xhdpi/ic_shuffle_white_24dp.png b/MusicDemo/src/main/res/drawable-xhdpi/ic_shuffle_white_24dp.png Binary files differnew file mode 100644 index 0000000..8ce3a60 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xhdpi/ic_shuffle_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png b/MusicDemo/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png Binary files differnew file mode 100644 index 0000000..f282b92 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png b/MusicDemo/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png Binary files differnew file mode 100644 index 0000000..2522877 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png b/MusicDemo/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png Binary files differnew file mode 100644 index 0000000..72dfa9f --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png b/MusicDemo/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png Binary files differnew file mode 100644 index 0000000..043acd8 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xxhdpi/ic_shuffle_white_24dp.png b/MusicDemo/src/main/res/drawable-xxhdpi/ic_shuffle_white_24dp.png Binary files differnew file mode 100644 index 0000000..718b6b5 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xxhdpi/ic_shuffle_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png b/MusicDemo/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png Binary files differnew file mode 100644 index 0000000..4fe6088 --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png diff --git a/MusicDemo/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png b/MusicDemo/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png Binary files differnew file mode 100644 index 0000000..2c9310a --- /dev/null +++ b/MusicDemo/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png diff --git a/MusicDemo/src/main/res/values-v21/styles.xml b/MusicDemo/src/main/res/values-v21/styles.xml index 6169d24..602ce1c 100644 --- a/MusicDemo/src/main/res/values-v21/styles.xml +++ b/MusicDemo/src/main/res/values-v21/styles.xml @@ -16,17 +16,17 @@ --> <resources> - <style name="AppBaseTheme" parent="Theme.AppCompat.Light"> + <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- colorPrimary is used for Notification icon and bottom facet bar icons and overflow actions --> - <item name="android:colorPrimary">@color/red</item> + <item name="android:colorPrimary">#ffff5722</item> <!-- colorPrimaryDark is used for background --> - <item name="android:colorPrimaryDark">#990000</item> + <item name="android:colorPrimaryDark">#ffbf360c</item> <!-- colorAccent is sparingly used for accents, like floating action button highlight, progress on playbar--> - <item name="android:colorAccent">#0000FF</item> + <item name="android:colorAccent">#ffff5722</item> </style> diff --git a/MusicDemo/src/main/res/values/colors.xml b/MusicDemo/src/main/res/values/colors.xml deleted file mode 100644 index 6a5277e..0000000 --- a/MusicDemo/src/main/res/values/colors.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources> - <color name="red">#ffff0000</color> -</resources> diff --git a/MusicDemo/src/main/res/values/styles.xml b/MusicDemo/src/main/res/values/styles.xml index 507dc7b..3be59c1 100644 --- a/MusicDemo/src/main/res/values/styles.xml +++ b/MusicDemo/src/main/res/values/styles.xml @@ -16,8 +16,11 @@ --> <resources> - <style name="AppBaseTheme" parent="Theme.AppCompat.Light"></style> - <style name="AppTheme" parent="AppBaseTheme"></style> + <style name="AppTheme" parent="AppBaseTheme"> + </style> + + <style name="AppBaseTheme" parent="android:Theme.Light"> + </style> </resources>
\ No newline at end of file |