1 /* 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 17 package com.android.music; 18 19 import android.app.Activity; 20 import android.app.ListActivity; 21 import android.content.*; 22 import android.database.Cursor; 23 import android.database.MatrixCursor; 24 import android.database.MergeCursor; 25 import android.database.sqlite.SQLiteException; 26 import android.media.AudioManager; 27 import android.media.MediaDescription; 28 import android.media.MediaMetadata; 29 import android.media.browse.MediaBrowser; 30 import android.media.session.MediaController; 31 import android.media.session.MediaSession; 32 import android.net.Uri; 33 import android.os.Bundle; 34 import android.provider.MediaStore; 35 import android.util.Log; 36 import android.view.LayoutInflater; 37 import android.view.View; 38 import android.view.ViewGroup; 39 import android.view.Window; 40 import android.widget.*; 41 import com.android.music.utils.LogHelper; 42 import com.android.music.utils.MediaIDHelper; 43 44 import java.text.Collator; 45 import java.util.ArrayList; 46 import java.util.List; 47 48 public class PlaylistBrowserActivity 49 extends ListActivity implements View.OnCreateContextMenuListener { 50 private static final String TAG = LogHelper.makeLogTag(PlaylistBrowserActivity.class); 51 private PlaylistListAdapter mAdapter; 52 boolean mAdapterSent; 53 private static final MediaBrowser.MediaItem DEFAULT_PARENT_ITEM = new MediaBrowser.MediaItem( 54 new MediaDescription.Builder() 55 .setMediaId(MediaIDHelper.MEDIA_ID_MUSICS_BY_PLAYLIST) 56 .setTitle("Playlists") 57 .build(), 58 MediaBrowser.MediaItem.FLAG_BROWSABLE); 59 60 private MediaBrowser mMediaBrowser; 61 private MediaBrowser.MediaItem mParentItem; 62 63 /** Called when the activity is first created. */ 64 @Override onCreate(Bundle icicle)65 public void onCreate(Bundle icicle) { 66 super.onCreate(icicle); 67 LogHelper.d(TAG, "onCreate()"); 68 // Process past states 69 Intent intent = getIntent(); 70 if (icicle != null) { 71 LogHelper.d(TAG, "Launch by saved instance state"); 72 mParentItem = icicle.getParcelable(MusicUtils.TAG_PARENT_ITEM); 73 MusicUtils.updateNowPlaying(this); 74 } else if (intent != null) { 75 LogHelper.d(TAG, "Launch by intent"); 76 mParentItem = intent.getExtras().getParcelable(MusicUtils.TAG_PARENT_ITEM); 77 } 78 if (mParentItem == null) { 79 LogHelper.d(TAG, "Launch by default parameters"); 80 mParentItem = DEFAULT_PARENT_ITEM; 81 } 82 requestWindowFeature(Window.FEATURE_NO_TITLE); 83 setVolumeControlStream(AudioManager.STREAM_MUSIC); 84 85 setTitle(R.string.playlists_title); 86 setContentView(R.layout.media_picker_activity); 87 MusicUtils.updateButtonBar(this, R.id.playlisttab); 88 ListView lv = getListView(); 89 lv.setOnCreateContextMenuListener(this); 90 lv.setTextFilterEnabled(true); 91 92 mAdapter = (PlaylistListAdapter) getLastNonConfigurationInstance(); 93 if (mAdapter == null) { 94 // Log.i("@@@", "starting query"); 95 mAdapter = new PlaylistListAdapter(this, R.layout.track_list_item); 96 setTitle(R.string.working_playlists); 97 } else { 98 mAdapter.setActivity(this); 99 } 100 setListAdapter(mAdapter); 101 Log.d(TAG, "Creating MediaBrowser"); 102 mMediaBrowser = new MediaBrowser(this, new ComponentName(this, MediaPlaybackService.class), 103 mConnectionCallback, null); 104 } 105 106 @Override onRetainNonConfigurationInstance()107 public Object onRetainNonConfigurationInstance() { 108 PlaylistListAdapter a = mAdapter; 109 mAdapterSent = true; 110 return a; 111 } 112 113 @Override onDestroy()114 public void onDestroy() { 115 setListAdapter(null); 116 mAdapter = null; 117 super.onDestroy(); 118 } 119 120 @Override onResume()121 public void onResume() { 122 super.onResume(); 123 } 124 125 @Override onPause()126 public void onPause() { 127 super.onPause(); 128 } 129 130 @Override onStart()131 public void onStart() { 132 Log.d(TAG, "onStart()"); 133 super.onStart(); 134 mMediaBrowser.connect(); 135 } 136 137 @Override onStop()138 public void onStop() { 139 Log.d(TAG, "onStop()"); 140 super.onStop(); 141 mMediaBrowser.disconnect(); 142 } 143 144 private MediaBrowser.SubscriptionCallback mSubscriptionCallback = 145 new MediaBrowser.SubscriptionCallback() { 146 147 @Override 148 public void onChildrenLoaded( 149 String parentId, List<MediaBrowser.MediaItem> children) { 150 mAdapter.clear(); 151 mAdapter.notifyDataSetInvalidated(); 152 for (MediaBrowser.MediaItem item : children) { 153 mAdapter.add(item); 154 } 155 mAdapter.notifyDataSetChanged(); 156 } 157 158 @Override 159 public void onError(String id) { 160 Toast.makeText(getApplicationContext(), R.string.error_loading_media, 161 Toast.LENGTH_LONG) 162 .show(); 163 } 164 }; 165 166 private MediaBrowser.ConnectionCallback mConnectionCallback = 167 new MediaBrowser.ConnectionCallback() { 168 @Override 169 public void onConnected() { 170 Log.d(TAG, "onConnected: session token " + mMediaBrowser.getSessionToken()); 171 mMediaBrowser.subscribe(mParentItem.getMediaId(), mSubscriptionCallback); 172 if (mMediaBrowser.getSessionToken() == null) { 173 throw new IllegalArgumentException("No Session token"); 174 } 175 MediaController mediaController = new MediaController( 176 PlaylistBrowserActivity.this, mMediaBrowser.getSessionToken()); 177 mediaController.registerCallback(mMediaControllerCallback); 178 PlaylistBrowserActivity.this.setMediaController(mediaController); 179 if (mediaController.getMetadata() != null) { 180 MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this); 181 } 182 } 183 184 @Override 185 public void onConnectionFailed() { 186 Log.d(TAG, "onConnectionFailed"); 187 } 188 189 @Override 190 public void onConnectionSuspended() { 191 Log.d(TAG, "onConnectionSuspended"); 192 PlaylistBrowserActivity.this.setMediaController(null); 193 } 194 }; 195 196 private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() { 197 @Override 198 public void onMetadataChanged(MediaMetadata metadata) { 199 super.onMetadataChanged(metadata); 200 MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this); 201 } 202 }; 203 204 private class PlaylistListAdapter extends ArrayAdapter<MediaBrowser.MediaItem> { 205 private int mLayoutId; 206 private Activity mActivity; 207 PlaylistListAdapter(PlaylistBrowserActivity currentactivity, int layout)208 PlaylistListAdapter(PlaylistBrowserActivity currentactivity, int layout) { 209 super(currentactivity, layout); 210 mActivity = currentactivity; 211 mLayoutId = layout; 212 } 213 214 private class ViewHolder { 215 TextView line1; 216 TextView line2; 217 ImageView icon; 218 ImageView play_indicator; 219 } 220 setActivity(PlaylistBrowserActivity newactivity)221 public void setActivity(PlaylistBrowserActivity newactivity) { 222 mActivity = newactivity; 223 } 224 225 @Override getView(int position, View convertView, ViewGroup parent)226 public View getView(int position, View convertView, ViewGroup parent) { 227 if (convertView == null) { 228 convertView = LayoutInflater.from(getContext()).inflate(mLayoutId, parent, false); 229 ViewHolder vhx = new ViewHolder(); 230 vhx.line1 = (TextView) convertView.findViewById(R.id.line1); 231 vhx.line2 = (TextView) convertView.findViewById(R.id.line2); 232 vhx.icon = (ImageView) convertView.findViewById(R.id.icon); 233 vhx.play_indicator = (ImageView) convertView.findViewById(R.id.play_indicator); 234 convertView.setTag(vhx); 235 } 236 ViewHolder vh = (ViewHolder) convertView.getTag(); 237 MediaBrowser.MediaItem item = getItem(position); 238 vh.line1.setText(item.getDescription().getTitle()); 239 vh.line2.setVisibility(View.GONE); 240 vh.play_indicator.setVisibility(View.GONE); 241 vh.icon.setImageResource(R.drawable.ic_mp_playlist_list); 242 ViewGroup.LayoutParams p = vh.icon.getLayoutParams(); 243 p.width = ViewGroup.LayoutParams.WRAP_CONTENT; 244 p.height = ViewGroup.LayoutParams.WRAP_CONTENT; 245 return convertView; 246 } 247 } 248 249 @Override onListItemClick(ListView l, View v, int position, long id)250 protected void onListItemClick(ListView l, View v, int position, long id) { 251 MediaBrowser.MediaItem item = mAdapter.getItem(position); 252 Intent intent = new Intent(Intent.ACTION_PICK); 253 intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track"); 254 intent.putExtra(MusicUtils.TAG_PARENT_ITEM, item); 255 startActivity(intent); 256 } 257 } 258