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 
MediaPickerActivity()43     public MediaPickerActivity()
44     {
45     }
46 
47     /** Called when the activity is first created. */
48     @Override
onCreate(Bundle icicle)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
onDestroy()68     public void onDestroy() {
69         MusicUtils.unbindFromService(mToken);
70         super.onDestroy();
71         if (mCursor != null) {
72             mCursor.close();
73         }
74     }
75 
init()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
onListItemClick(ListView l, View v, int position, long id)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 
MakeCursor()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 
PickListAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to)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
newView(Context context, Cursor cursor, ViewGroup parent)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
bindView(View view, Context context, Cursor cursor)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