void setSelected(Cursor c) { Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; long newId = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Audio.Media._ID)); mSelectedUri = ContentUris.withAppendedId(uri, newId); mSelectedId = newId; if (newId != mPlayingId || mMediaPlayer == null) { stopMediaPlayer(); mMediaPlayer = new MediaPlayer(); try { mMediaPlayer.setDataSource(this, mSelectedUri); mMediaPlayer.setOnCompletionListener(this); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.prepare(); mMediaPlayer.start(); mPlayingId = newId; } catch (IOException e) { MusicLogUtils.e(TAG, "Unable to play track", e); /// M: finally just get invalidate list view @{ } finally { getListView().invalidateViews(); } /// @} } else if (mMediaPlayer != null) { stopMediaPlayer(); getListView().invalidateViews(); } }
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); String status = Environment.getExternalStorageState(); MusicLogUtils.d(TAG, "mScanListener.onReceive:" + action + ", status = " + status); if (Intent.ACTION_MEDIA_SCANNER_STARTED.equals(action) || Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)) { MusicUtils.setSpinnerState(MusicPicker.this); } doQuery(false, null); }
/** * This method is called whenever we receive a new cursor due to an async query, and must take * care of plugging the new one in to the adapter. */ @Override public void changeCursor(Cursor cursor) { super.changeCursor(cursor); MusicLogUtils.v( TAG, "changeCursor cursor to: " + cursor + " from: " + MusicPicker.this.mCursor); MusicPicker.this.mCursor = cursor; if (cursor != null) { // Retrieve indices of the various columns we are interested in. mIdIdx = cursor.getColumnIndex(MediaStore.Audio.Media._ID); mTitleIdx = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE); mArtistIdx = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST); mAlbumIdx = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM); mDurationIdx = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION); /// M: Retrieve indices of the IS_DRM and DRM_METHOD @{ mIsDrmIdx = cursor.getColumnIndex(MediaStore.Audio.Media.IS_DRM); mDrmMethodIdx = cursor.getColumnIndex(MediaStore.Audio.Media.DRM_METHOD); /// @} // If the sort mode has changed, or we haven't yet created an // indexer one, then create a new one that is indexing the // appropriate column based on the sort mode. if (mIndexerSortMode != mSortMode || mIndexer == null) { mIndexerSortMode = mSortMode; /// M: Add for Chinese sort with title, artist or album. int idx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE_PINYIN_KEY); switch (mIndexerSortMode) { case ARTIST_MENU: idx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Artists.ARTIST_PINYIN_KEY); break; case ALBUM_MENU: idx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM_PINYIN_KEY); break; } mIndexer = new MusicAlphabetIndexer( cursor, idx, getResources().getString(R.string.fast_scroll_alphabet)); // If we have a valid indexer, but the cursor has changed since // its last use, then point it to the current cursor. } else { mIndexer.setCursor(cursor); } } /// M: Show empty view instead. // Ensure that the list is shown (and initial progress indicator // hidden) in case this is the first cursor we have gotten. // makeListShown(); }
@Override protected void onListItemClick(ListView l, View v, int position, long id) { mCursor.moveToPosition(position); mSelectedPos = position; MusicLogUtils.v( TAG, "Click on " + position + " (id=" + id + ", cursid=" + mCursor.getLong(mCursor.getColumnIndex(MediaStore.Audio.Media._ID)) + ") in cursor " + mCursor + " adapter=" + l.getAdapter()); setSelected(mCursor); }
/** * Common method for performing a query of the music database, called for both top-level queries * and filtering. * * @param sync If true, this query should be done synchronously and the resulting cursor returned. * If false, it will be done asynchronously and null returned. * @param filterstring If non-null, this is a filter to apply to the query. */ Cursor doQuery(boolean sync, String filterstring) { MusicLogUtils.d(TAG, "doQuery(" + sync + ", " + filterstring + ")"); // Cancel any pending queries mQueryHandler.cancelOperation(MY_QUERY_TOKEN); StringBuilder where = new StringBuilder(); where.append(MediaStore.Audio.Media.TITLE + " != ''"); /// M: determine the Dim level for query @{ if (MusicFeatureOption.IS_SUPPORT_DRM) { String sIsDrm = MediaStore.Audio.Media.IS_DRM; String sDrmMethod = MediaStore.Audio.Media.DRM_METHOD; switch (mDrmLevel) { case OmaDrmStore.DrmExtra.DRM_LEVEL_FL: where.append( " AND (" + sIsDrm + "!=1 OR (" + sIsDrm + "=1" + " AND " + sDrmMethod + "=" + OmaDrmStore.DrmMethod.METHOD_FL + "))"); break; case OmaDrmStore.DrmExtra.DRM_LEVEL_SD: where.append( " AND (" + sIsDrm + "!=1 OR (" + sIsDrm + "=1" + " AND " + sDrmMethod + "=" + OmaDrmStore.DrmMethod.METHOD_SD + "))"); break; case OmaDrmStore.DrmExtra.DRM_LEVEL_ALL: break; case -1: default: // this intent does not contain DRM Extras where.append(" AND " + sIsDrm + "!=1"); break; } MusicLogUtils.d(TAG, "doQuery: where=" + where); } /// @} // We want to show all audio files, even recordings. Enforcing the // following condition would hide recordings. // where.append(" AND " + MediaStore.Audio.Media.IS_MUSIC + "=1"); Uri uri = mBaseUri; if (!TextUtils.isEmpty(filterstring)) { uri = uri.buildUpon().appendQueryParameter("filter", Uri.encode(filterstring)).build(); } if (sync) { try { return getContentResolver().query(uri, CURSOR_COLS, where.toString(), null, mSortOrder); } catch (UnsupportedOperationException ex) { } } else { mAdapter.setLoading(true); mQueryHandler.startQuery( MY_QUERY_TOKEN, null, uri, CURSOR_COLS, where.toString(), null, mSortOrder); } return null; }
/** * Called when the activity is first created. * * @param icicle */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); /// M: set the music style Audio. setVolumeControlStream(AudioManager.STREAM_MUSIC); int sortMode = TRACK_MENU; if (icicle == null) { mSelectedUri = getIntent().getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); /// M: Retrieve the Drmlevel from intent @{ mDrmLevel = getIntent().getIntExtra(OmaDrmStore.DrmExtra.EXTRA_DRM_LEVEL, -1); MusicLogUtils.d(TAG, "onCreate: drmlevel=" + mDrmLevel); /// @} } else { mSelectedUri = (Uri) icicle.getParcelable(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); // Retrieve list state. This will be applied after the // QueryHandler has run. mListState = icicle.getParcelable(LIST_STATE_KEY); mListHasFocus = icicle.getBoolean(FOCUS_KEY); sortMode = icicle.getInt(SORT_MODE_KEY, sortMode); /// M: Returns the value associated with the given key(SELECTED_POS|DRM_LEVEL), or // defaultValue // if no mapping of the desired type exists for the given key. @{ mPrevSelectedPos = icicle.getInt(SELECTED_POS, -1); mDrmLevel = icicle.getInt(DRM_LEVEL, -1); MusicLogUtils.d( TAG, "onCreate: drmlevel(restored) = " + mDrmLevel + ", mSelectedUri = " + mSelectedUri); /// @} } if (Intent.ACTION_GET_CONTENT.equals(getIntent().getAction())) { mBaseUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } else { mBaseUri = getIntent().getData(); if (mBaseUri == null) { MusicLogUtils.w(TAG, "No data URI given to PICK action"); finish(); return; } } setContentView(R.layout.music_picker); /// M: Creates a DrmManagerClient. if (MusicFeatureOption.IS_SUPPORT_DRM) { mDrmClient = new OmaDrmClient(this); } /// M: add for chinese sorting mSortOrder = MediaStore.Audio.Media.TITLE_PINYIN_KEY; final ListView listView = getListView(); listView.setItemsCanFocus(false); mAdapter = new TrackListAdapter( this, listView, R.layout.music_picker_item, new String[] {}, new int[] {}); setListAdapter(mAdapter); listView.setTextFilterEnabled(true); // We manually save/restore the listview state listView.setSaveEnabled(false); mQueryHandler = new QueryHandler(this); // mProgressContainer = findViewById(R.id.progressContainer); // mListContainer = findViewById(R.id.listContainer); mOkayButton = findViewById(R.id.okayButton); mOkayButton.setOnClickListener(this); /// M: Only when user select a audio we need set ok button enable. mOkayButton.setEnabled(false); mCancelButton = findViewById(R.id.cancelButton); mCancelButton.setOnClickListener(this); // If there is a currently selected Uri, then try to determine who // it is. if (mSelectedUri != null) { Uri.Builder builder = mSelectedUri.buildUpon(); String path = mSelectedUri.getEncodedPath(); int idx = path.lastIndexOf('/'); if (idx >= 0) { path = path.substring(0, idx); } builder.encodedPath(path); Uri baseSelectedUri = builder.build(); MusicLogUtils.v(TAG, "Selected Uri: " + mSelectedUri); MusicLogUtils.v(TAG, "Selected base Uri: " + baseSelectedUri); MusicLogUtils.v(TAG, "Base Uri: " + mBaseUri); if (baseSelectedUri.equals(mBaseUri)) { // If the base Uri of the selected Uri is the same as our // content's base Uri, then use the selection! mSelectedId = ContentUris.parseId(mSelectedUri); } } /// M: add IntentFilter action and register a Listener for SD card status changed @{ IntentFilter f = new IntentFilter(); f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); f.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); f.addAction(Intent.ACTION_MEDIA_UNMOUNTED); f.addAction(Intent.ACTION_MEDIA_MOUNTED); f.addDataScheme("file"); registerReceiver(mScanListener, f); /// @} mIsBroadcastReg = true; setSortMode(sortMode); }
/** * This method is called from a background thread by the list view when the user has typed a * letter that should result in a filtering of the displayed items. It returns a Cursor, when * will then be handed to changeCursor. */ @Override public Cursor runQueryOnBackgroundThread(CharSequence constraint) { MusicLogUtils.v(TAG, "Getting new cursor..."); return doQuery(true, constraint.toString()); }
@Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder vh = (ViewHolder) view.getTag(); cursor.copyStringToBuffer(mTitleIdx, vh.buffer1); vh.line1.setText(vh.buffer1.data, 0, vh.buffer1.sizeCopied); final int secondUnit = 1000; int secs = cursor.getInt(mDurationIdx) / secondUnit; if (secs == 0) { vh.duration.setText(""); } else { vh.duration.setText(MusicUtils.makeTimeString(context, secs)); } final StringBuilder builder = mBuilder; builder.delete(0, builder.length()); String name = cursor.getString(mAlbumIdx); if (name == null || name.equals("<unknown>")) { builder.append(mUnknownAlbum); } else { builder.append(name); } builder.append('\n'); name = cursor.getString(mArtistIdx); if (name == null || name.equals("<unknown>")) { builder.append(mUnknownArtist); } else { builder.append(name); } int len = builder.length(); if (vh.buffer2.length < len) { vh.buffer2 = new char[len]; } builder.getChars(0, len, vh.buffer2, 0); vh.line2.setText(vh.buffer2, 0, len); // Update the checkbox of the item, based on which the user last // selected. Note that doing it this way means we must have the // list view update all of its items when the selected item // changes. final long id = cursor.getLong(mIdIdx); vh.radio.setChecked(id == mSelectedId); MusicLogUtils.v( TAG, "Binding id=" + id + " sel=" + mSelectedId + " playing=" + mPlayingId + " cursor=" + cursor); // Likewise, display the "now playing" icon if this item is // currently being previewed for the user. ImageView iv = vh.play_indicator; if (id == mPlayingId) { iv.setVisibility(View.VISIBLE); } else { /// M: if current song is not playing , we don't need the ImageView of play_indicator // visible. iv.setVisibility(View.GONE); } /// M: Show drm lock when necessary @{ updateDrmLockIcon(vh.drmLock, cursor, id); }
/** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setVolumeControlStream(AudioManager.STREAM_MUSIC); int sortMode = TRACK_MENU; if (icicle == null) { mSelectedUri = getIntent().getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); mDrmLevel = getIntent().getIntExtra(DrmStore.DrmExtra.EXTRA_DRM_LEVEL, -1); MusicLogUtils.d(TAG, "onCreate: drmlevel=" + mDrmLevel); } else { mSelectedUri = (Uri) icicle.getParcelable(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); // Retrieve list state. This will be applied after the // QueryHandler has run mListState = icicle.getParcelable(LIST_STATE_KEY); mListHasFocus = icicle.getBoolean(FOCUS_KEY); sortMode = icicle.getInt(SORT_MODE_KEY, sortMode); mPrevSelectedPos = icicle.getInt(SELECTED_POS, -1); mDrmLevel = icicle.getInt(DRM_LEVEL, -1); MusicLogUtils.d(TAG, "onCreate: drmlevel(restored)=" + mDrmLevel); } if (Intent.ACTION_GET_CONTENT.equals(getIntent().getAction())) { mBaseUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } else { mBaseUri = getIntent().getData(); if (mBaseUri == null) { MusicLogUtils.w(TAG, "No data URI given to PICK action"); finish(); return; } } setContentView(R.layout.music_picker); LinearLayout mainLayout = (LinearLayout) findViewById(R.id.mainLayout); /* if (FeatureOption.MTK_THEMEMANAGER_APP) { mainLayout.setThemeContentBgColor(0xff000000); } */ mSortOrder = MediaStore.Audio.Media.TITLE_KEY; if (FeatureOption.MTK_DRM_APP) { mDrmClient = new DrmManagerClient(this); } final ListView listView = getListView(); listView.setItemsCanFocus(false); mAdapter = new TrackListAdapter( this, listView, R.layout.music_picker_item, new String[] {}, new int[] {}); setListAdapter(mAdapter); listView.setTextFilterEnabled(true); // We manually save/restore the listview state listView.setSaveEnabled(false); mQueryHandler = new QueryHandler(this); mProgressContainer = findViewById(R.id.progressContainer); mListContainer = findViewById(R.id.listContainer); mOkayButton = findViewById(R.id.okayButton); mOkayButton.setOnClickListener(this); mCancelButton = findViewById(R.id.cancelButton); mCancelButton.setOnClickListener(this); // If there is a currently selected Uri, then try to determine who // it is. if (mSelectedUri != null) { Uri.Builder builder = mSelectedUri.buildUpon(); String path = mSelectedUri.getEncodedPath(); int idx = path.lastIndexOf('/'); if (idx >= 0) { path = path.substring(0, idx); } builder.encodedPath(path); Uri baseSelectedUri = builder.build(); MusicLogUtils.v(TAG, "Selected Uri: " + mSelectedUri); MusicLogUtils.v(TAG, "Selected base Uri: " + baseSelectedUri); MusicLogUtils.v(TAG, "Base Uri: " + mBaseUri); if (baseSelectedUri.equals(mBaseUri)) { // If the base Uri of the selected Uri is the same as our // content's base Uri, then use the selection! mSelectedId = ContentUris.parseId(mSelectedUri); } } setSortMode(sortMode); }
@Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder vh = (ViewHolder) view.getTag(); cursor.copyStringToBuffer(mTitleIdx, vh.buffer1); vh.line1.setText(vh.buffer1.data, 0, vh.buffer1.sizeCopied); int secs = cursor.getInt(mDurationIdx) / 1000; if (secs == 0) { vh.duration.setText(""); } else { vh.duration.setText(MusicUtils.makeTimeString(context, secs)); } final StringBuilder builder = mBuilder; builder.delete(0, builder.length()); String name = cursor.getString(mAlbumIdx); if (name == null || name.equals("<unknown>")) { builder.append(mUnknownAlbum); } else { builder.append(name); } builder.append('\n'); name = cursor.getString(mArtistIdx); if (name == null || name.equals("<unknown>")) { builder.append(mUnknownArtist); } else { builder.append(name); } int len = builder.length(); if (vh.buffer2.length < len) { vh.buffer2 = new char[len]; } builder.getChars(0, len, vh.buffer2, 0); vh.line2.setText(vh.buffer2, 0, len); // Update the checkbox of the item, based on which the user last // selected. Note that doing it this way means we must have the // list view update all of its items when the selected item // changes. final long id = cursor.getLong(mIdIdx); vh.radio.setChecked(id == mSelectedId); MusicLogUtils.v( TAG, "Binding id=" + id + " sel=" + mSelectedId + " playing=" + mPlayingId + " cursor=" + cursor); // Likewise, display the "now playing" icon if this item is // currently being previewed for the user. ImageView iv = vh.play_indicator; if (id == mPlayingId) { iv.setImageResource(R.drawable.indicator_ic_mp_playing_list); iv.setVisibility(View.VISIBLE); } else { iv.setVisibility(View.GONE); } // Show drm lock when necessary iv = vh.drm_lock; if (FeatureOption.MTK_DRM_APP) { int isDRM = cursor.getInt(mIsDrmIdx); int drmMethod = cursor.getInt(mDrmMethodIdx); MusicLogUtils.d(TAG, "bindView(" + view + "): isDRM=" + isDRM + ", drmMethod=" + drmMethod); try { if (isDRM == 1 && drmMethod != DrmStore.DrmMethod.METHOD_FL) { if (mDrmClient.checkRightsStatus( ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id), DrmStore.Action.PLAY) == DrmStore.RightsStatus.RIGHTS_VALID) { iv.setImageResource(com.mediatek.internal.R.drawable.drm_green_lock); } else { iv.setImageResource(com.mediatek.internal.R.drawable.drm_red_lock); } iv.setVisibility(View.VISIBLE); } else { iv.setVisibility(View.GONE); } } catch (Exception ex) { MusicLogUtils.e(TAG, "bindView: ", ex); iv.setVisibility(View.GONE); } } else { iv.setVisibility(View.GONE); } }