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
17package com.android.music;
18
19import com.android.music.MusicUtils.ServiceToken;
20
21import android.app.ListActivity;
22import android.content.Context;
23import android.content.Intent;
24import android.content.ContentUris;
25import android.database.Cursor;
26import android.net.Uri;
27import android.os.Bundle;
28import android.os.RemoteException;
29import android.provider.MediaStore;
30import android.view.View;
31import android.view.ViewGroup;
32import android.widget.ImageView;
33import android.widget.ListView;
34import android.widget.SimpleCursorAdapter;
35import android.widget.TextView;
36
37import java.util.ArrayList;
38
39public 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