/* * ServeStream: A HTTP stream browser/player for Android * Copyright 2010 William Seemann * * 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 pontezit.android.tilos.com.utils; import android.app.Activity; import android.app.Service; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.ServiceConnection; import android.database.Cursor; import android.net.Uri; import android.os.RemoteException; import android.util.Log; import android.widget.Toast; import java.util.Formatter; import java.util.HashMap; import java.util.Locale; import pontezit.android.tilos.com.R; import pontezit.android.tilos.com.service.IMediaPlaybackService; import pontezit.android.tilos.com.service.MediaPlaybackService; public class MusicUtils { public interface Defs { public final static int OPEN_URL = 0; public final static int ADD_TO_PLAYLIST = 1; public final static int USE_AS_RINGTONE = 2; public final static int PLAYLIST_SELECTED = 3; public final static int NEW_PLAYLIST = 4; public final static int PLAY_SELECTION = 5; public final static int GOTO_START = 6; public final static int GOTO_PLAYBACK = 7; public final static int PARTY_SHUFFLE = 8; public final static int SHUFFLE_ALL = 9; public final static int DELETE_ITEM = 10; public final static int SCAN_DONE = 11; public final static int QUEUE = 12; public final static int EFFECTS_PANEL = 13; public final static int CHILD_MENU_BASE = 14; // this should be the last item } public static IMediaPlaybackService sService = null; private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>(); public static class ServiceToken { ContextWrapper mWrappedContext; ServiceToken(ContextWrapper context) { mWrappedContext = context; } } public static ServiceToken bindToService(Activity context, ServiceConnection callback) { LogHelper.Log("bindToService run;"); Activity realActivity = context.getParent(); if (realActivity == null) { LogHelper.Log("bindToService; realActivity == null"); realActivity = context; } ContextWrapper cw = new ContextWrapper(realActivity); cw.startService(new Intent(cw, MediaPlaybackService.class)); ServiceBinder sb = new ServiceBinder(callback); if (cw.bindService((new Intent()).setClass(cw, MediaPlaybackService.class), sb, 0)) { sConnectionMap.put(cw, sb); return new ServiceToken(cw); } Log.e("Music", "Failed to bind to service"); return null; } public static ServiceToken bindToService(Service context, ServiceConnection callback) { ContextWrapper cw = new ContextWrapper(context); cw.startService(new Intent(cw, MediaPlaybackService.class)); ServiceBinder sb = new ServiceBinder(callback); if (cw.bindService((new Intent()).setClass(cw, MediaPlaybackService.class), sb, 0)) { sConnectionMap.put(cw, sb); return new ServiceToken(cw); } Log.e("Music", "Failed to bind to service"); return null; } public static void unbindFromService(ServiceToken token) { if (token == null) { Log.e("MusicUtils", "Trying to unbind with null token"); return; } ContextWrapper cw = token.mWrappedContext; ServiceBinder sb = sConnectionMap.remove(cw); if (sb == null) { Log.e("MusicUtils", "Trying to unbind for unknown Context"); return; } cw.unbindService(sb); if (sConnectionMap.isEmpty()) { // presumably there is nobody interested in the service at this point, // so don't hang on to the ServiceConnection sService = null; } } private static class ServiceBinder implements ServiceConnection { ServiceConnection mCallback; ServiceBinder(ServiceConnection callback) { mCallback = callback; } public void onServiceConnected(ComponentName className, android.os.IBinder service) { sService = IMediaPlaybackService.Stub.asInterface(service); if (mCallback != null) { mCallback.onServiceConnected(className, service); } } public void onServiceDisconnected(ComponentName className) { if (mCallback != null) { mCallback.onServiceDisconnected(className); } sService = null; } } /* 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(); } public static void play(Context context, String path, Boolean fromService){ if(sService == null) LogHelper.Log("MusicUtils; mService null!!!!!"); LogHelper.Log("Musicutils.play running;" + path); int flags; if(fromService) flags = Intent.FLAG_ACTIVITY_NEW_TASK; else flags = Intent.FLAG_ACTIVITY_CLEAR_TOP; if (path != null && (path.length() == 0 || sService == null)){ Log.d("MusicUtils", "attempt to play empty song list"); // Don't try to play empty playlists. Nothing good will come of it. String message = context.getString(R.string.playback_failed); Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); return; } try { sService.openStream(path); } catch (RemoteException ex) { } finally { Intent intent = new Intent("pontezit.android.tilos.com.PLAYBACK_VIEWER").setFlags(flags); context.startActivity(intent); } } }