blob: ce5dcab50fced05034d9b3c4cd8fa2e6e6b17ccc [file] [log] [blame]
The Android Open Source Project792a2202009-03-03 19:32:30 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.music;
18
19import android.app.ListActivity;
Marco Nelissenec0c57a2009-12-12 12:27:11 -080020import android.content.ComponentName;
The Android Open Source Project792a2202009-03-03 19:32:30 -080021import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
The Android Open Source Project792a2202009-03-03 19:32:30 -080024import android.graphics.Bitmap;
25import android.graphics.BitmapFactory;
26import android.graphics.drawable.BitmapDrawable;
27import android.graphics.drawable.Drawable;
28import android.media.AudioManager;
Jack Hef02d3c62017-02-21 00:39:22 -050029import android.media.MediaDescription;
30import android.media.MediaMetadata;
31import android.media.browse.MediaBrowser;
32import android.media.session.MediaController;
33import android.media.session.MediaSession;
34import android.media.session.PlaybackState;
The Android Open Source Project792a2202009-03-03 19:32:30 -080035import android.net.Uri;
36import android.os.Bundle;
Marco Nelissen9882f542009-08-14 10:06:15 -070037import android.util.Log;
Jack Hef02d3c62017-02-21 00:39:22 -050038import android.view.LayoutInflater;
The Android Open Source Project792a2202009-03-03 19:32:30 -080039import android.view.View;
40import android.view.ViewGroup;
41import android.view.Window;
Jack Hef02d3c62017-02-21 00:39:22 -050042import android.widget.*;
43import com.android.music.utils.LogHelper;
44import com.android.music.utils.MediaIDHelper;
45import com.android.music.utils.Playback;
The Android Open Source Project792a2202009-03-03 19:32:30 -080046
Jack Hef02d3c62017-02-21 00:39:22 -050047import java.util.ArrayList;
48import java.util.List;
The Android Open Source Project792a2202009-03-03 19:32:30 -080049
Jack Hef02d3c62017-02-21 00:39:22 -050050/*
51This activity is the albums browsing tab
52 */
53public class AlbumBrowserActivity extends ListActivity {
54 private static final String TAG = LogHelper.makeLogTag(AlbumBrowserActivity.class);
55 private static final MediaBrowser.MediaItem DEFAULT_PARENT_ITEM =
56 new MediaBrowser.MediaItem(new MediaDescription.Builder()
57 .setMediaId(MediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM)
58 .build(),
59 MediaBrowser.MediaItem.FLAG_BROWSABLE);
The Android Open Source Project792a2202009-03-03 19:32:30 -080060
Jack Hef02d3c62017-02-21 00:39:22 -050061 private ListView mAlbumList;
62 private AlbumBrowseAdapter mBrowseListAdapter;
63 private MediaBrowser mMediaBrowser;
64 private MediaBrowser.MediaItem mParentItem;
The Android Open Source Project792a2202009-03-03 19:32:30 -080065
66 /** Called when the activity is first created. */
67 @Override
Jack Heb0fba8b2017-01-26 15:54:38 -080068 public void onCreate(Bundle icicle) {
Jack Hef02d3c62017-02-21 00:39:22 -050069 Log.d(TAG, "onCreate()");
The Android Open Source Project792a2202009-03-03 19:32:30 -080070 super.onCreate(icicle);
Jack Hef02d3c62017-02-21 00:39:22 -050071 if (icicle != null) {
72 mParentItem = icicle.getParcelable(MusicUtils.TAG_PARENT_ITEM);
73 } else if (getIntent() != null) {
74 mParentItem = getIntent().getExtras().getParcelable(MusicUtils.TAG_PARENT_ITEM);
75 }
76 if (mParentItem == null) {
77 mParentItem = DEFAULT_PARENT_ITEM;
78 }
Marco Nelissenec0c57a2009-12-12 12:27:11 -080079 requestWindowFeature(Window.FEATURE_NO_TITLE);
The Android Open Source Project792a2202009-03-03 19:32:30 -080080 setVolumeControlStream(AudioManager.STREAM_MUSIC);
The Android Open Source Project792a2202009-03-03 19:32:30 -080081
82 setContentView(R.layout.media_picker_activity);
Marco Nelissenec0c57a2009-12-12 12:27:11 -080083 MusicUtils.updateButtonBar(this, R.id.albumtab);
Jack Hef02d3c62017-02-21 00:39:22 -050084 mAlbumList = getListView();
85 mAlbumList.setOnCreateContextMenuListener(this);
86 mAlbumList.setTextFilterEnabled(true);
The Android Open Source Project792a2202009-03-03 19:32:30 -080087
Jack Hef02d3c62017-02-21 00:39:22 -050088 mBrowseListAdapter = (AlbumBrowseAdapter) getLastNonConfigurationInstance();
89 if (mBrowseListAdapter == null) {
Jack Heb0fba8b2017-01-26 15:54:38 -080090 // Log.i("@@@", "starting query");
Jack Hef02d3c62017-02-21 00:39:22 -050091 mBrowseListAdapter = new AlbumBrowseAdapter(this, R.layout.track_list_item);
The Android Open Source Project792a2202009-03-03 19:32:30 -080092 setTitle(R.string.working_albums);
The Android Open Source Project792a2202009-03-03 19:32:30 -080093 }
Jack Hef02d3c62017-02-21 00:39:22 -050094 setListAdapter(mBrowseListAdapter);
95 Log.d(TAG, "Creating MediaBrowser");
96 mMediaBrowser = new MediaBrowser(this, new ComponentName(this, MediaPlaybackService.class),
97 mConnectionCallback, null);
The Android Open Source Project792a2202009-03-03 19:32:30 -080098 }
99
100 @Override
101 public void onDestroy() {
Jack Hef02d3c62017-02-21 00:39:22 -0500102 Log.d(TAG, "onDestroy()");
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800103 ListView lv = getListView();
Marco Nelissen0164ebf2009-08-13 09:58:43 -0700104 // Because we pass the adapter to the next activity, we need to make
105 // sure it doesn't keep a reference to this activity. We can do this
106 // by clearing its DatasetObservers, which setListAdapter(null) does.
107 setListAdapter(null);
Jack Hef02d3c62017-02-21 00:39:22 -0500108 mBrowseListAdapter = null;
The Android Open Source Project792a2202009-03-03 19:32:30 -0800109 super.onDestroy();
110 }
Jack Heb0fba8b2017-01-26 15:54:38 -0800111
The Android Open Source Project792a2202009-03-03 19:32:30 -0800112 @Override
113 public void onResume() {
Jack Hef02d3c62017-02-21 00:39:22 -0500114 Log.d(TAG, "onResume()");
The Android Open Source Project792a2202009-03-03 19:32:30 -0800115 super.onResume();
The Android Open Source Project792a2202009-03-03 19:32:30 -0800116 }
117
Jack Hef02d3c62017-02-21 00:39:22 -0500118 @Override
119 public void onStart() {
120 Log.d(TAG, "onStart()");
121 super.onStart();
122 mMediaBrowser.connect();
123 }
Jack Heb0fba8b2017-01-26 15:54:38 -0800124
Jack Hef02d3c62017-02-21 00:39:22 -0500125 @Override
126 public void onStop() {
127 Log.d(TAG, "onStop()");
128 super.onStop();
129 mMediaBrowser.disconnect();
130 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800131
132 @Override
133 public void onPause() {
Jack Hef02d3c62017-02-21 00:39:22 -0500134 Log.d(TAG, "onPause()");
The Android Open Source Project792a2202009-03-03 19:32:30 -0800135 super.onPause();
136 }
137
Jack Hef02d3c62017-02-21 00:39:22 -0500138 @Override
139 public void onSaveInstanceState(Bundle outcicle) {
140 outcicle.putParcelable(MusicUtils.TAG_PARENT_ITEM, mParentItem);
141 super.onSaveInstanceState(outcicle);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800142 }
143
144 private void setTitle() {
145 CharSequence fancyName = "";
Jack Hef02d3c62017-02-21 00:39:22 -0500146 setTitle(R.string.albums_title);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800147 }
Marco Nelissen9882f542009-08-14 10:06:15 -0700148
Jack Hef02d3c62017-02-21 00:39:22 -0500149 private MediaBrowser.SubscriptionCallback mSubscriptionCallback =
150 new MediaBrowser.SubscriptionCallback() {
The Android Open Source Project792a2202009-03-03 19:32:30 -0800151
Jack Hef02d3c62017-02-21 00:39:22 -0500152 @Override
153 public void onChildrenLoaded(
154 String parentId, List<MediaBrowser.MediaItem> children) {
155 mBrowseListAdapter.clear();
156 mBrowseListAdapter.notifyDataSetInvalidated();
157 for (MediaBrowser.MediaItem item : children) {
158 mBrowseListAdapter.add(item);
159 }
160 mBrowseListAdapter.notifyDataSetChanged();
Eric Fischerecf5b652010-10-18 14:20:30 -0700161 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800162
Jack Hef02d3c62017-02-21 00:39:22 -0500163 @Override
164 public void onError(String id) {
165 Toast.makeText(getApplicationContext(), R.string.error_loading_media,
166 Toast.LENGTH_LONG)
167 .show();
The Android Open Source Project792a2202009-03-03 19:32:30 -0800168 }
Jack Hef02d3c62017-02-21 00:39:22 -0500169 };
The Android Open Source Project792a2202009-03-03 19:32:30 -0800170
Jack Hef02d3c62017-02-21 00:39:22 -0500171 private MediaBrowser.ConnectionCallback mConnectionCallback =
172 new MediaBrowser.ConnectionCallback() {
173 @Override
174 public void onConnected() {
175 Log.d(TAG, "onConnected: session token " + mMediaBrowser.getSessionToken());
176 mMediaBrowser.subscribe(mParentItem.getMediaId(), mSubscriptionCallback);
177 if (mMediaBrowser.getSessionToken() == null) {
178 throw new IllegalArgumentException("No Session token");
179 }
180 MediaController mediaController = new MediaController(
181 AlbumBrowserActivity.this, mMediaBrowser.getSessionToken());
182 mediaController.registerCallback(mMediaControllerCallback);
183 AlbumBrowserActivity.this.setMediaController(mediaController);
184 if (mediaController.getMetadata() != null) {
185 MusicUtils.updateNowPlaying(AlbumBrowserActivity.this);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800186 }
187 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800188
Jack Hef02d3c62017-02-21 00:39:22 -0500189 @Override
190 public void onConnectionFailed() {
191 Log.d(TAG, "onConnectionFailed");
The Android Open Source Project792a2202009-03-03 19:32:30 -0800192 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800193
Jack Hef02d3c62017-02-21 00:39:22 -0500194 @Override
195 public void onConnectionSuspended() {
196 Log.d(TAG, "onConnectionSuspended");
197 AlbumBrowserActivity.this.setMediaController(null);
198 }
199 };
Marco Nelissen89f6c662010-09-02 15:20:23 -0700200
Jack Hef02d3c62017-02-21 00:39:22 -0500201 private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
202 @Override
203 public void onMetadataChanged(MediaMetadata metadata) {
204 super.onMetadataChanged(metadata);
205 MusicUtils.updateNowPlaying(AlbumBrowserActivity.this);
206 if (mBrowseListAdapter != null) {
207 mBrowseListAdapter.notifyDataSetChanged();
The Android Open Source Project792a2202009-03-03 19:32:30 -0800208 }
209 }
Jack Hef02d3c62017-02-21 00:39:22 -0500210 };
Jack Heb0fba8b2017-01-26 15:54:38 -0800211
Jack Hef02d3c62017-02-21 00:39:22 -0500212 // An adapter for showing the list of browsed MediaItem's
213 private class AlbumBrowseAdapter extends ArrayAdapter<MediaBrowser.MediaItem> {
The Android Open Source Project792a2202009-03-03 19:32:30 -0800214 private final Drawable mNowPlayingOverlay;
215 private final BitmapDrawable mDefaultAlbumIcon;
Jack Hef02d3c62017-02-21 00:39:22 -0500216 private int mLayoutId;
Jack Heb0fba8b2017-01-26 15:54:38 -0800217
Jack Hef02d3c62017-02-21 00:39:22 -0500218 private class ViewHolder {
The Android Open Source Project792a2202009-03-03 19:32:30 -0800219 TextView line1;
220 TextView line2;
The Android Open Source Project792a2202009-03-03 19:32:30 -0800221 ImageView play_indicator;
222 ImageView icon;
223 }
224
Jack Hef02d3c62017-02-21 00:39:22 -0500225 AlbumBrowseAdapter(Context context, int layout) {
226 super(context, layout, new ArrayList<>());
227 mNowPlayingOverlay = context.getResources().getDrawable(
228 R.drawable.indicator_ic_mp_playing_list, context.getTheme());
229 Bitmap b = BitmapFactory.decodeResource(
230 context.getResources(), R.drawable.albumart_mp_unknown_list);
Marco Nelissen5df7af32009-08-19 10:21:29 -0700231 mDefaultAlbumIcon = new BitmapDrawable(context.getResources(), b);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800232 // no filter or dither, it's a lot faster and we can't tell the difference
233 mDefaultAlbumIcon.setFilterBitmap(false);
234 mDefaultAlbumIcon.setDither(false);
Jack Hef02d3c62017-02-21 00:39:22 -0500235 mLayoutId = layout;
The Android Open Source Project792a2202009-03-03 19:32:30 -0800236 }
237
238 @Override
Jack Hef02d3c62017-02-21 00:39:22 -0500239 public View getView(int position, View convertView, ViewGroup parent) {
240 Log.d(TAG, "getView()");
241 if (convertView == null) {
242 convertView = LayoutInflater.from(getContext()).inflate(mLayoutId, parent, false);
243 ViewHolder vh = new ViewHolder();
244 vh.line1 = (TextView) convertView.findViewById(R.id.line1);
245 vh.line2 = (TextView) convertView.findViewById(R.id.line2);
246 vh.play_indicator = (ImageView) convertView.findViewById(R.id.play_indicator);
247 vh.icon = (ImageView) convertView.findViewById(R.id.icon);
248 vh.icon.setBackground(mDefaultAlbumIcon);
249 vh.icon.setPadding(0, 0, 1, 0);
250 vh.icon.setVisibility(View.VISIBLE);
251 convertView.setTag(vh);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800252 }
Jack Hef02d3c62017-02-21 00:39:22 -0500253 ViewHolder vh = (ViewHolder) convertView.getTag();
254 MediaBrowser.MediaItem item = getItem(position);
255 Log.d(TAG, "Album: " + item.getDescription().getTitle());
256 vh.line1.setText(item.getDescription().getTitle());
257 Log.d(TAG, "Artist: " + item.getDescription().getSubtitle());
258 vh.line2.setText(item.getDescription().getSubtitle());
259 Bitmap albumArt = item.getDescription().getIconBitmap();
260 LogHelper.d(TAG, "looking for album art");
261 if (albumArt != null) {
262 vh.icon.setImageDrawable(MusicUtils.getDrawableBitmap(albumArt, mDefaultAlbumIcon));
The Android Open Source Project792a2202009-03-03 19:32:30 -0800263 } else {
Jack Hef02d3c62017-02-21 00:39:22 -0500264 vh.icon.setImageDrawable(mDefaultAlbumIcon);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800265 }
Jack Hef02d3c62017-02-21 00:39:22 -0500266 MediaController mediaController = AlbumBrowserActivity.this.getMediaController();
267 if (mediaController == null) {
268 vh.play_indicator.setImageDrawable(null);
269 return convertView;
270 }
271 MediaMetadata metadata = mediaController.getMetadata();
272 if (metadata == null) {
273 vh.play_indicator.setImageDrawable(null);
274 return convertView;
275 }
276 if (metadata.getString(MediaMetadata.METADATA_KEY_ALBUM)
277 .equals(item.getDescription().getTitle())) {
278 vh.play_indicator.setImageDrawable(mNowPlayingOverlay);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800279 } else {
Jack Hef02d3c62017-02-21 00:39:22 -0500280 vh.play_indicator.setImageDrawable(null);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800281 }
Jack Hef02d3c62017-02-21 00:39:22 -0500282 return convertView;
The Android Open Source Project792a2202009-03-03 19:32:30 -0800283 }
284 }
285
Jack Hef02d3c62017-02-21 00:39:22 -0500286 @Override
287 protected void onListItemClick(ListView l, View v, int position, long id) {
288 Log.d(TAG, "onListItemClick at position " + position + ", id " + id);
289 MediaBrowser.MediaItem item = mBrowseListAdapter.getItem(position);
290 if (item.isBrowsable()) {
291 Intent intent = new Intent(Intent.ACTION_PICK);
292 intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
293 intent.putExtra(MusicUtils.TAG_PARENT_ITEM, item);
294 intent.putExtra(MusicUtils.TAG_WITH_TABS, false);
295 startActivity(intent);
296 }
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800297 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800298}