InputStream
as a byte[]
.
*
* This method buffers the input internally, so there is no need to use a
* BufferedInputStream
.
*
* @param input the InputStream
to read from
* @return the requested byte array
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
*/
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
copy(input, output);
return output.toByteArray();
}
public static long copy(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[1024 * 4];
long count = 0;
int n;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
public static void atomicCopy(File from, File to) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
File tmp = null;
try {
tmp = new File(to.getPath() + ".tmp");
in = new FileInputStream(from);
out = new FileOutputStream(tmp);
in.getChannel().transferTo(0, from.length(), out.getChannel());
out.close();
if (!tmp.renameTo(to)) {
throw new IOException("Failed to rename " + tmp + " to " + to);
}
Log.i(TAG, "Copied " + from + " to " + to);
} catch (IOException x) {
close(out);
delete(to);
throw x;
} finally {
close(in);
close(out);
delete(tmp);
}
}
public static void renameFile(File from, File to) throws IOException {
if(from.renameTo(to)) {
Log.i(TAG, "Renamed " + from + " to " + to);
} else {
atomicCopy(from, to);
}
}
public static void close(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (Throwable x) {
// Ignored
}
}
public static boolean delete(File file) {
if (file != null && file.exists()) {
if (!file.delete()) {
Log.w(TAG, "Failed to delete file " + file);
return false;
}
Log.i(TAG, "Deleted file " + file);
}
return true;
}
public static boolean recursiveDelete(File dir) {
if (dir != null && dir.exists()) {
for(File file: dir.listFiles()) {
if(file.isDirectory()) {
if(!recursiveDelete(file)) {
return false;
}
} else if(file.exists()) {
if(!file.delete()) {
return false;
}
}
}
return dir.delete();
}
return false;
}
public static void toast(Context context, int messageId) {
toast(context, messageId, true);
}
public static void toast(Context context, int messageId, boolean shortDuration) {
toast(context, context.getString(messageId), shortDuration);
}
public static void toast(Context context, String message) {
toast(context, message, true);
}
public static void toast(Context context, String message, boolean shortDuration) {
if (toast == null) {
toast = Toast.makeText(context, message, shortDuration ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
} else {
toast.setText(message);
toast.setDuration(shortDuration ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG);
}
toast.show();
}
/**
* Converts a byte-count to a formatted string suitable for display to the user.
* For instance:
* format(918)
returns "918 B".format(98765)
returns "96 KB".format(1238476)
returns "1.2 MB".format(918)
returns "918 B".format(98765)
returns "96 KB".format(1238476)
returns "1.2 MB".Broadcasts the given song info as the new song being played.
*/ public static void broadcastNewTrackInfo(Context context, MusicDirectory.Entry song) { Intent intent = new Intent(EVENT_META_CHANGED); if (song != null) { intent.putExtra("title", song.getTitle()); intent.putExtra("artist", song.getArtist()); intent.putExtra("album", song.getAlbum()); File albumArtFile = FileUtil.getAlbumArtFile(context, song); intent.putExtra("coverart", albumArtFile.getAbsolutePath()); } else { intent.putExtra("title", ""); intent.putExtra("artist", ""); intent.putExtra("album", ""); intent.putExtra("coverart", ""); } context.sendBroadcast(intent); } public static void broadcastA2dpMetaDataChange(Context context, DownloadService downloadService) { Entry song = null; Intent avrcpIntent = new Intent(CM_AVRCP_METADATA_CHANGED); if (downloadService != null) { DownloadFile entry = downloadService.getCurrentPlaying(); if (entry != null) { song = entry.getSong(); } } if (downloadService == null || song == null) { avrcpIntent.putExtra("track", ""); avrcpIntent.putExtra("track_name", ""); avrcpIntent.putExtra("artist", ""); avrcpIntent.putExtra("artist_name", ""); avrcpIntent.putExtra("album", ""); avrcpIntent.putExtra("album_name", ""); avrcpIntent.putExtra("cover", (Parcelable) null); avrcpIntent.putExtra("coverart", (Parcelable) null); avrcpIntent.putExtra("ListSize", (long) 0); avrcpIntent.putExtra("id", (long) 0); avrcpIntent.putExtra("duration", (long) 0); avrcpIntent.putExtra("position", (long) 0); bluetoothBitmap = null; } else { if (song != currentSong) { currentSong = song; bluetoothBitmap = FileUtil.getAlbumArtBitmap(context, song, bluetoothImagesize, true); } String title = song.getTitle(); String artist = song.getArtist(); String album = song.getAlbum(); Integer duration = song.getDuration(); Integer listSize = downloadService.getDownloads().size(); Integer id = downloadService.getCurrentPlayingIndex() + 1; Integer playerPosition = downloadService.getPlayerPosition(); avrcpIntent.putExtra("track", title); avrcpIntent.putExtra("track_name", title); avrcpIntent.putExtra("artist", artist); avrcpIntent.putExtra("artist_name", artist); avrcpIntent.putExtra("album", album); avrcpIntent.putExtra("album_name", album); avrcpIntent.putExtra("cover", (Parcelable) bluetoothBitmap); avrcpIntent.putExtra("coverart", (Parcelable) bluetoothBitmap); if (playerPosition != null) { avrcpIntent.putExtra("position", (long) playerPosition); } if (id != null) { avrcpIntent.putExtra("id", (long) id); } if (listSize != null) { avrcpIntent.putExtra("ListSize", (long) listSize); } if (duration != null) { avrcpIntent.putExtra("duration", (long) duration); } } context.sendBroadcast(avrcpIntent); } public static void broadcastA2dpPlayStatusChange(Context context, PlayerState state, DownloadService downloadService) { if (downloadService.getCurrentPlaying() != null) { Intent avrcpIntent = new Intent(CM_AVRCP_PLAYSTATE_CHANGED); Entry song = downloadService.getCurrentPlaying().getSong(); if (song == null) { return; } if (song != currentSong) { currentSong = song; bluetoothBitmap = FileUtil.getAlbumArtBitmap(context, song, bluetoothImagesize, true); } String title = song.getTitle(); String artist = song.getArtist(); String album = song.getAlbum(); Integer duration = song.getDuration(); Integer listSize = downloadService.getDownloads().size(); Integer id = downloadService.getCurrentPlayingIndex() + 1; Integer playerPosition = downloadService.getPlayerPosition(); avrcpIntent.putExtra("track", title); avrcpIntent.putExtra("track_name", title); avrcpIntent.putExtra("artist", artist); avrcpIntent.putExtra("artist_name", artist); avrcpIntent.putExtra("album", album); avrcpIntent.putExtra("album_name", album); avrcpIntent.putExtra("cover", (Parcelable) bluetoothBitmap); avrcpIntent.putExtra("coverart", (Parcelable) bluetoothBitmap); if (playerPosition != null) { avrcpIntent.putExtra("position", (long) playerPosition); } if (id != null) { avrcpIntent.putExtra("id", (long) id); } if (listSize != null) { avrcpIntent.putExtra("ListSize", (long) listSize); } if (duration != null) { avrcpIntent.putExtra("duration", (long) duration); } switch (state) { case STARTED: avrcpIntent.putExtra("playing", true); break; case STOPPED: avrcpIntent.putExtra("playing", false); break; case PAUSED: avrcpIntent.putExtra("playing", false); break; case COMPLETED: avrcpIntent.putExtra("playing", false); break; default: return; // No need to broadcast. } context.sendBroadcast(avrcpIntent); } } /** *Broadcasts the given player state as the one being set.
*/ public static void broadcastPlaybackStatusChange(Context context, PlayerState state) { Intent intent = new Intent(EVENT_PLAYSTATE_CHANGED); switch (state) { case STARTED: intent.putExtra("state", "play"); break; case STOPPED: intent.putExtra("state", "stop"); break; case PAUSED: intent.putExtra("state", "pause"); break; case COMPLETED: intent.putExtra("state", "complete"); break; default: return; // No need to broadcast. } context.sendBroadcast(intent); } public static int getNotificationImageSize(Context context) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); int imageSizeLarge = (int) Math.round(Math.min(metrics.widthPixels, metrics.heightPixels)); int size = 64; if (imageSizeLarge <= 480) { size = 64; } else if (imageSizeLarge <= 768) { size = 128; } else { size = 256; } return size; } public static int getAlbumImageSize(Context context) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); int imageSizeLarge = (int) Math.round(Math.min(metrics.widthPixels, metrics.heightPixels)); int size = 128; if (imageSizeLarge <= 480) { size = 128; } else if (imageSizeLarge <= 768) { size = 256; } else { size = 512; } return size; } public static void requestAudioFocus(final Context context) { if (!hasFocus) { final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); hasFocus = true; audioManager.requestAudioFocus(new OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { DownloadServiceImpl downloadService = (DownloadServiceImpl)context; if((focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) && !downloadService.isJukeboxEnabled()) { if(downloadService.getPlayerState() == PlayerState.STARTED) { SharedPreferences prefs = getPreferences(context); int lossPref = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1")); if(lossPref == 2 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)) { lowerFocus = true; downloadService.setVolume(0.1f); } else if(lossPref == 0 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)) { pauseFocus = true; downloadService.pause(); } } } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { if(pauseFocus) { pauseFocus = false; downloadService.start(); } else if(lowerFocus) { lowerFocus = false; downloadService.setVolume(1.0f); } } else if(focusChange == AudioManager.AUDIOFOCUS_LOSS && !downloadService.isJukeboxEnabled()) { hasFocus = false; downloadService.pause(); audioManager.abandonAudioFocus(this); } } }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); } } public static int getMinDisplayMetric(Context context) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); return Math.min(metrics.widthPixels, metrics.heightPixels); } public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate ratios of height and width to requested height and // width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will // guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path, options); } public static void linkButtons(Context context, RemoteViews views, boolean playerActive) { Intent intent = new Intent(context, playerActive ? DownloadActivity.class : MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.appwidget_coverart, pendingIntent); views.setOnClickPendingIntent(R.id.appwidget_top, pendingIntent); // Emulate media button clicks. intent = new Intent("1"); intent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_play, pendingIntent); intent = new Intent("2"); intent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT)); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_next, pendingIntent); intent = new Intent("3"); intent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS)); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_previous, pendingIntent); intent = new Intent("4"); intent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_STOP)); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_stop, pendingIntent); } public static int getMaxVideoBitrate(Context context) { ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = manager.getActiveNetworkInfo(); if (networkInfo == null) { return 0; } boolean wifi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI; SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(wifi ? Constants.PREFERENCES_KEY_MAX_VIDEO_BITRATE_WIFI : Constants.PREFERENCES_KEY_MAX_VIDEO_BITRATE_MOBILE, "0")); } public static int getNetworkTimeout(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_NETWORK_TIMEOUT, "15000")); } public static int getDefaultAlbums(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_DEFAULT_ALBUMS, "5")); } public static int getMaxAlbums(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_MAX_ALBUMS, "20")); } public static int getDefaultSongs(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_DEFAULT_SONGS, "10")); } public static int getMaxSongs(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_MAX_SONGS, "25")); } public static int getMaxArtists(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_MAX_ARTISTS, "10")); } public static int getDefaultArtists(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_DEFAULT_ARTISTS, "3")); } public static int getBufferLength(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_BUFFER_LENGTH, "5")); } public static int getIncrementTime(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_INCREMENT_TIME, "5")); } public static boolean getMediaButtonsPreference(Context context) { SharedPreferences prefs = getPreferences(context); return prefs.getBoolean(Constants.PREFERENCES_KEY_MEDIA_BUTTONS, true); } public static boolean getShowNowPlayingPreference(Context context) { SharedPreferences prefs = getPreferences(context); return prefs.getBoolean(Constants.PREFERENCES_KEY_SHOW_NOW_PLAYING, true); } public static boolean getGaplessPlaybackPreference(Context context) { SharedPreferences prefs = getPreferences(context); return prefs.getBoolean(Constants.PREFERENCES_KEY_GAPLESS_PLAYBACK, true); } public static boolean getShouldTransitionOnPlaybackPreference(Context context) { SharedPreferences prefs = getPreferences(context); return prefs.getBoolean(Constants.PREFERENCES_KEY_DOWNLOAD_TRANSITION, true); } public static boolean getShouldUseId3Tags(Context context) { SharedPreferences prefs = getPreferences(context); return prefs.getBoolean(Constants.PREFERENCES_KEY_ID3_TAGS, false); } public static int getChatRefreshInterval(Context context) { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_CHAT_REFRESH_INTERVAL, "5000")); } public static boolean isNullOrWhiteSpace(String string) { return string == null || string.isEmpty() || string.trim().isEmpty(); } public static String formatTotalDuration(long totalDuration) { long millis = totalDuration * 1000; long hours = TimeUnit.MILLISECONDS.toHours(millis); long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(hours); long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(hours * 60 + minutes); if (hours >= 10) { return String.format("%02d:%02d:%02d", hours, minutes, seconds); } else if (hours > 0) { return String.format("%d:%02d:%02d", hours, minutes, seconds); } else if (minutes >= 10) { return String.format("%02d:%02d", minutes, seconds); } else if (minutes > 0) { return String.format("%d:%02d", minutes, seconds); } else { return String.format("0:%02d", seconds); } } }