| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.music; |
| |
| import android.app.Activity; |
| import android.content.ContentResolver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.SharedPreferences; |
| import android.content.SharedPreferences.Editor; |
| import android.content.res.Resources; |
| import android.database.Cursor; |
| import android.graphics.Bitmap; |
| import android.graphics.Canvas; |
| import android.graphics.ColorFilter; |
| import android.graphics.PixelFormat; |
| import android.graphics.drawable.BitmapDrawable; |
| import android.graphics.drawable.Drawable; |
| import android.media.MediaMetadata; |
| import android.media.session.MediaController; |
| import android.net.Uri; |
| import android.provider.MediaStore; |
| import android.view.View; |
| import android.widget.TabWidget; |
| import android.widget.TextView; |
| import com.android.music.utils.LogHelper; |
| import com.android.music.utils.MusicProvider; |
| |
| import java.util.Formatter; |
| import java.util.Iterator; |
| import java.util.Locale; |
| |
| /* |
| Static methods useful for activities |
| */ |
| public class MusicUtils { |
| private static final String TAG = LogHelper.makeLogTag(MusicUtils.class); |
| |
| public static final String TAG_MEDIA_ID = "__MEDIA_ID"; |
| public static final String TAG_PARENT_ITEM = "__PARENT_ITEM"; |
| public static final String TAG_WITH_TABS = "__WITH_TABS"; |
| |
| // A really simple BitmapDrawable-like class, that doesn't do |
| // scaling, dithering or filtering. |
| private static class FastBitmapDrawable extends Drawable { |
| private Bitmap mBitmap; |
| public FastBitmapDrawable(Bitmap b) { |
| mBitmap = b; |
| } |
| @Override |
| public void draw(Canvas canvas) { |
| canvas.drawBitmap(mBitmap, 0, 0, null); |
| } |
| @Override |
| public int getOpacity() { |
| return PixelFormat.OPAQUE; |
| } |
| @Override |
| public void setAlpha(int alpha) {} |
| @Override |
| public void setColorFilter(ColorFilter cf) {} |
| } |
| |
| public static Bitmap resizeBitmap(Bitmap bitmap, Bitmap ref) { |
| int w = ref.getWidth(); |
| int h = ref.getHeight(); |
| return Bitmap.createScaledBitmap(bitmap, w, h, false); |
| } |
| |
| public static Drawable getDrawableBitmap(Bitmap bitmap, BitmapDrawable defaultArtwork) { |
| final Bitmap icon = defaultArtwork.getBitmap(); |
| int w = icon.getWidth(); |
| int h = icon.getHeight(); |
| bitmap = Bitmap.createScaledBitmap(bitmap, w, h, false); |
| return new FastBitmapDrawable(bitmap); |
| } |
| |
| public static String makeAlbumsLabel( |
| Context context, int numalbums, int numsongs, boolean isUnknown) { |
| // There are two formats for the albums/songs information: |
| // "N Song(s)" - used for unknown artist/album |
| // "N Album(s)" - used for known albums |
| |
| StringBuilder songs_albums = new StringBuilder(); |
| |
| Resources r = context.getResources(); |
| if (isUnknown) { |
| if (numsongs == 1) { |
| songs_albums.append(context.getString(R.string.onesong)); |
| } else { |
| String f = r.getQuantityText(R.plurals.Nsongs, numsongs).toString(); |
| sFormatBuilder.setLength(0); |
| sFormatter.format(f, Integer.valueOf(numsongs)); |
| songs_albums.append(sFormatBuilder); |
| } |
| } else { |
| String f = r.getQuantityText(R.plurals.Nalbums, numalbums).toString(); |
| sFormatBuilder.setLength(0); |
| sFormatter.format(f, Integer.valueOf(numalbums)); |
| songs_albums.append(sFormatBuilder); |
| songs_albums.append(context.getString(R.string.albumsongseparator)); |
| } |
| return songs_albums.toString(); |
| } |
| |
| /** |
| * This is now only used for the query screen |
| */ |
| public static String makeAlbumsSongsLabel( |
| Context context, int numalbums, int numsongs, boolean isUnknown) { |
| // There are several formats for the albums/songs information: |
| // "1 Song" - used if there is only 1 song |
| // "N Songs" - used for the "unknown artist" item |
| // "1 Album"/"N Songs" |
| // "N Album"/"M Songs" |
| // Depending on locale, these may need to be further subdivided |
| |
| StringBuilder songs_albums = new StringBuilder(); |
| |
| if (numsongs == 1) { |
| songs_albums.append(context.getString(R.string.onesong)); |
| } else { |
| Resources r = context.getResources(); |
| if (!isUnknown) { |
| String f = r.getQuantityText(R.plurals.Nalbums, numalbums).toString(); |
| sFormatBuilder.setLength(0); |
| sFormatter.format(f, Integer.valueOf(numalbums)); |
| songs_albums.append(sFormatBuilder); |
| songs_albums.append(context.getString(R.string.albumsongseparator)); |
| } |
| String f = r.getQuantityText(R.plurals.Nsongs, numsongs).toString(); |
| sFormatBuilder.setLength(0); |
| sFormatter.format(f, Integer.valueOf(numsongs)); |
| songs_albums.append(sFormatBuilder); |
| } |
| return songs_albums.toString(); |
| } |
| |
| /* Try to use String.format() as little as possible, because it creates a |
| * new Formatter every time you call it, which is very inefficient. |
| * Reusing an existing Formatter more than tripled the speed of |
| * makeTimeString(). |
| * This Formatter/StringBuilder are also used by makeAlbumSongsLabel() |
| */ |
| private static StringBuilder sFormatBuilder = new StringBuilder(); |
| private static Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault()); |
| private static final Object[] sTimeArgs = new Object[5]; |
| |
| public static String makeTimeString(Context context, long secs) { |
| String durationformat = context.getString( |
| secs < 3600 ? R.string.durationformatshort : R.string.durationformatlong); |
| |
| /* Provide multiple arguments so the format can be changed easily |
| * by modifying the xml. |
| */ |
| sFormatBuilder.setLength(0); |
| |
| final Object[] timeArgs = sTimeArgs; |
| timeArgs[0] = secs / 3600; |
| timeArgs[1] = secs / 60; |
| timeArgs[2] = (secs / 60) % 60; |
| timeArgs[3] = secs; |
| timeArgs[4] = secs % 60; |
| |
| return sFormatter.format(durationformat, timeArgs).toString(); |
| } |
| |
| static int getIntPref(Context context, String name, int def) { |
| SharedPreferences prefs = |
| context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); |
| return prefs.getInt(name, def); |
| } |
| |
| static void setIntPref(Context context, String name, int value) { |
| SharedPreferences prefs = |
| context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); |
| Editor ed = prefs.edit(); |
| ed.putInt(name, value); |
| SharedPreferencesCompat.apply(ed); |
| } |
| |
| static int sActiveTabIndex = -1; |
| |
| static boolean updateButtonBar(Activity a, int highlight) { |
| final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar); |
| boolean withtabs = false; |
| Intent intent = a.getIntent(); |
| if (intent != null) { |
| withtabs = intent.getBooleanExtra(MusicUtils.TAG_WITH_TABS, false); |
| } |
| |
| if (highlight == 0 || !withtabs) { |
| ll.setVisibility(View.GONE); |
| return withtabs; |
| } else if (withtabs) { |
| ll.setVisibility(View.VISIBLE); |
| } |
| for (int i = ll.getChildCount() - 1; i >= 0; i--) { |
| View v = ll.getChildAt(i); |
| boolean isActive = (v.getId() == highlight); |
| if (isActive) { |
| ll.setCurrentTab(i); |
| sActiveTabIndex = i; |
| } |
| v.setTag(i); |
| v.setOnFocusChangeListener(new View.OnFocusChangeListener() { |
| |
| public void onFocusChange(View v, boolean hasFocus) { |
| if (hasFocus) { |
| for (int i = 0; i < ll.getTabCount(); i++) { |
| if (ll.getChildTabViewAt(i) == v) { |
| ll.setCurrentTab(i); |
| processTabClick((Activity) ll.getContext(), v, |
| ll.getChildAt(sActiveTabIndex).getId()); |
| break; |
| } |
| } |
| } |
| } |
| }); |
| |
| v.setOnClickListener(new View.OnClickListener() { |
| |
| public void onClick(View v) { |
| processTabClick( |
| (Activity) ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId()); |
| } |
| }); |
| } |
| return withtabs; |
| } |
| |
| static void processTabClick(Activity a, View v, int current) { |
| int id = v.getId(); |
| if (id == current) { |
| return; |
| } |
| |
| final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar); |
| |
| activateTab(a, id); |
| if (id != R.id.nowplayingtab) { |
| ll.setCurrentTab((Integer) v.getTag()); |
| setIntPref(a, "activetab", id); |
| } |
| } |
| |
| static void activateTab(Activity a, int id) { |
| Intent intent = new Intent(Intent.ACTION_PICK); |
| switch (id) { |
| case R.id.artisttab: |
| intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/artistalbum"); |
| break; |
| case R.id.albumtab: |
| intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album"); |
| break; |
| case R.id.songtab: |
| intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track"); |
| break; |
| case R.id.playlisttab: |
| intent.setDataAndType(Uri.EMPTY, MediaStore.Audio.Playlists.CONTENT_TYPE); |
| break; |
| case R.id.nowplayingtab: |
| intent = new Intent(a, MediaPlaybackActivity.class); |
| a.startActivity(intent); |
| // fall through and return |
| default: |
| return; |
| } |
| intent.putExtra(MusicUtils.TAG_WITH_TABS, true); |
| intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); |
| a.startActivity(intent); |
| a.finish(); |
| a.overridePendingTransition(0, 0); |
| } |
| |
| static void updateNowPlaying(Activity a) { |
| View nowPlayingView = a.findViewById(R.id.nowplaying); |
| if (nowPlayingView == null) { |
| return; |
| } |
| MediaController controller = a.getMediaController(); |
| if (controller != null) { |
| MediaMetadata metadata = controller.getMetadata(); |
| if (metadata != null) { |
| TextView title = (TextView) nowPlayingView.findViewById(R.id.title); |
| TextView artist = (TextView) nowPlayingView.findViewById(R.id.artist); |
| title.setText(metadata.getString(MediaMetadata.METADATA_KEY_TITLE)); |
| String artistName = metadata.getString(MediaMetadata.METADATA_KEY_ARTIST); |
| if (MusicProvider.UNKOWN.equals(artistName)) { |
| artistName = a.getString(R.string.unknown_artist_name); |
| } |
| artist.setText(artistName); |
| nowPlayingView.setVisibility(View.VISIBLE); |
| nowPlayingView.setOnClickListener(new View.OnClickListener() { |
| public void onClick(View v) { |
| Context c = v.getContext(); |
| c.startActivity(new Intent(c, MediaPlaybackActivity.class)); |
| } |
| }); |
| return; |
| } |
| } |
| nowPlayingView.setVisibility(View.GONE); |
| } |
| } |