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 com.android.music.MusicUtils.ServiceToken; 20 21 import android.app.ListActivity; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.ContentUris; 25 import android.database.Cursor; 26 import android.net.Uri; 27 import android.os.Bundle; 28 import android.os.RemoteException; 29 import android.provider.MediaStore; 30 import android.view.View; 31 import android.view.ViewGroup; 32 import android.widget.ImageView; 33 import android.widget.ListView; 34 import android.widget.SimpleCursorAdapter; 35 import android.widget.TextView; 36 37 import java.util.ArrayList; 38 39 public class MediaPickerActivity extends ListActivity implements MusicUtils.Defs 40 { 41 private ServiceToken mToken; 42 43 public MediaPickerActivity() 44 { 45 } 46 47 /** Called when the activity is first created. */ 48 @Override 49 public void onCreate(Bundle icicle) 50 { 51 super.onCreate(icicle); 52 53 mFirstYear = getIntent().getStringExtra("firstyear"); 54 mLastYear = getIntent().getStringExtra("lastyear"); 55 56 if (mFirstYear == null) { 57 setTitle(R.string.all_title); 58 } else if (mFirstYear.equals(mLastYear)) { 59 setTitle(mFirstYear); 60 } else { 61 setTitle(mFirstYear + "-" + mLastYear); 62 } 63 mToken = MusicUtils.bindToService(this); 64 init(); 65 } 66 67 @Override 68 public void onDestroy() { 69 MusicUtils.unbindFromService(mToken); 70 super.onDestroy(); 71 if (mCursor != null) { 72 mCursor.close(); 73 } 74 } 75 76 public void init() { 77 78 setContentView(R.layout.media_picker_activity); 79 80 MakeCursor(); 81 if (null == mCursor || 0 == mCursor.getCount()) { 82 return; 83 } 84 85 PickListAdapter adapter = new PickListAdapter( 86 this, 87 R.layout.track_list_item, 88 mCursor, 89 new String[] {}, 90 new int[] {}); 91 92 setListAdapter(adapter); 93 } 94 95 @Override 96 protected void onListItemClick(ListView l, View v, int position, long id) 97 { 98 mCursor.moveToPosition(position); 99 String type = mCursor.getString(mCursor.getColumnIndexOrThrow( 100 MediaStore.Audio.Media.MIME_TYPE)); 101 102 String action = getIntent().getAction(); 103 if (Intent.ACTION_GET_CONTENT.equals(action)) { 104 Uri uri; 105 106 long mediaId; 107 if (type.startsWith("video")) { 108 uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 109 mediaId = mCursor.getLong(mCursor.getColumnIndexOrThrow( 110 MediaStore.Video.Media._ID)); 111 } else { 112 uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 113 mediaId = mCursor.getLong(mCursor.getColumnIndexOrThrow( 114 MediaStore.Audio.Media._ID)); 115 } 116 117 setResult(RESULT_OK, new Intent().setData(ContentUris.withAppendedId(uri, mediaId))); 118 finish(); 119 return; 120 } 121 122 // Need to stop the playbackservice, in case it is busy playing audio 123 // and the user selected a video. 124 if (MusicUtils.sService != null) { 125 try { 126 MusicUtils.sService.stop(); 127 } catch (RemoteException ex) { 128 } 129 } 130 Intent intent = new Intent(Intent.ACTION_VIEW); 131 intent.setDataAndType(ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id), type); 132 133 startActivity(intent); 134 } 135 136 private void MakeCursor() { 137 String[] audiocols = new String[] { 138 MediaStore.Audio.Media._ID, 139 MediaStore.Audio.Media.ARTIST, 140 MediaStore.Audio.Media.ALBUM, 141 MediaStore.Audio.Media.TITLE, 142 MediaStore.Audio.Media.DATA, 143 MediaStore.Audio.Media.MIME_TYPE, 144 MediaStore.Audio.Media.YEAR 145 }; 146 String[] videocols = new String[] { 147 MediaStore.Audio.Media._ID, 148 MediaStore.Audio.Media.TITLE, 149 MediaStore.Audio.Media.ARTIST, 150 MediaStore.Audio.Media.ALBUM, 151 MediaStore.Audio.Media.TITLE, 152 MediaStore.Audio.Media.DATA, 153 MediaStore.Audio.Media.MIME_TYPE 154 }; 155 156 Cursor[] cs; 157 // Use ArrayList for the moment, since we don't know the size of 158 // Cursor[]. If the length of Corsor[] larger than really used, 159 // a NPE will come up when access the content of Corsor[]. 160 ArrayList<Cursor> cList = new ArrayList<Cursor>(); 161 Intent intent = getIntent(); 162 String type = intent.getType(); 163 164 if (mFirstYear != null) { 165 // If mFirstYear is not null, the picker only for audio because 166 // video has no year column. 167 if(type.equals("video/*")) { 168 mCursor = null; 169 return; 170 } 171 172 mWhereClause = MediaStore.Audio.Media.YEAR + ">=" + mFirstYear + " AND " + 173 MediaStore.Audio.Media.YEAR + "<=" + mLastYear; 174 } 175 176 // If use Cursor[] as before, the Cursor[i] could be null when there is 177 // no video/audio/sdcard. Then a NPE will come up when access the content of the 178 // Array. 179 180 Cursor c; 181 if (type.equals("video/*")) { 182 // Only video. 183 c = MusicUtils.query(this, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, 184 videocols, null , null, mSortOrder); 185 if (c != null) { 186 cList.add(c); 187 } 188 } else { 189 c = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 190 audiocols, mWhereClause , null, mSortOrder); 191 192 if (c != null) { 193 cList.add(c); 194 } 195 196 if (mFirstYear == null && intent.getType().equals("media/*")) { 197 // video has no year column 198 c = MusicUtils.query(this, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, 199 videocols, null , null, mSortOrder); 200 if (c != null) { 201 cList.add(c); 202 } 203 } 204 } 205 206 // Get the ArrayList size. 207 int size = cList.size(); 208 if (0 == size) { 209 // If no video/audio/SDCard exist, return. 210 mCursor = null; 211 return; 212 } 213 214 // The size is known now, we're sure each item of Cursor[] is not null. 215 cs = new Cursor[size]; 216 cs = cList.toArray(cs); 217 mCursor = new SortCursor(cs, MediaStore.Audio.Media.TITLE); 218 } 219 220 private Cursor mCursor; 221 private String mSortOrder = MediaStore.Audio.Media.TITLE + " COLLATE UNICODE"; 222 private String mFirstYear; 223 private String mLastYear; 224 private String mWhereClause; 225 226 static class PickListAdapter extends SimpleCursorAdapter { 227 int mTitleIdx; 228 int mArtistIdx; 229 int mAlbumIdx; 230 int mMimeIdx; 231 232 PickListAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to) { 233 super(context, layout, cursor, from, to); 234 235 mTitleIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE); 236 mArtistIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST); 237 mAlbumIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM); 238 mMimeIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.MIME_TYPE); 239 } 240 241 @Override 242 public View newView(Context context, Cursor cursor, ViewGroup parent) { 243 View v = super.newView(context, cursor, parent); 244 ImageView iv = (ImageView) v.findViewById(R.id.icon); 245 iv.setVisibility(View.VISIBLE); 246 ViewGroup.LayoutParams p = iv.getLayoutParams(); 247 p.width = ViewGroup.LayoutParams.WRAP_CONTENT; 248 p.height = ViewGroup.LayoutParams.WRAP_CONTENT; 249 250 TextView tv = (TextView) v.findViewById(R.id.duration); 251 tv.setVisibility(View.GONE); 252 iv = (ImageView) v.findViewById(R.id.play_indicator); 253 iv.setVisibility(View.GONE); 254 255 return v; 256 } 257 258 @Override 259 public void bindView(View view, Context context, Cursor cursor) { 260 261 TextView tv = (TextView) view.findViewById(R.id.line1); 262 String name = cursor.getString(mTitleIdx); 263 tv.setText(name); 264 265 tv = (TextView) view.findViewById(R.id.line2); 266 name = cursor.getString(mAlbumIdx); 267 StringBuilder builder = new StringBuilder(); 268 if (name == null || name.equals(MediaStore.UNKNOWN_STRING)) { 269 builder.append(context.getString(R.string.unknown_album_name)); 270 } else { 271 builder.append(name); 272 } 273 builder.append("\n"); 274 name = cursor.getString(mArtistIdx); 275 if (name == null || name.equals(MediaStore.UNKNOWN_STRING)) { 276 builder.append(context.getString(R.string.unknown_artist_name)); 277 } else { 278 builder.append(name); 279 } 280 tv.setText(builder.toString()); 281 282 String text = cursor.getString(mMimeIdx); 283 ImageView iv = (ImageView) view.findViewById(R.id.icon);; 284 if("audio/midi".equals(text)) { 285 iv.setImageResource(R.drawable.midi); 286 } else if(text != null && (text.startsWith("audio") || 287 text.equals("application/ogg") || 288 text.equals("application/x-ogg"))) { 289 iv.setImageResource(R.drawable.ic_search_category_music_song); 290 } else if(text != null && text.startsWith("video")) { 291 iv.setImageResource(R.drawable.movie); 292 } else { 293 iv.setImageResource(0); 294 } 295 } 296 } 297 } 298