package com.teleca.jamendo; import java.io.File; import java.util.ArrayList; import android.app.Application; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Environment; import android.preference.PreferenceManager; import android.util.Log; import com.teleca.jamendo.activity.playview.PlayMethod; import com.teleca.jamendo.api.IPlayEngine; import com.teleca.jamendo.api.IPlayEngineListener; import com.teleca.jamendo.api.IServerApi; import com.teleca.jamendo.model.Playlist; import com.teleca.jamendo.service.DownloadService; import com.teleca.jamendo.service.PlayerService; import com.teleca.jamendo.util.Caller; import com.teleca.jamendo.util.ImgCache; import com.teleca.jamendo.util.RequestCache; import com.teleca.jamendo.util.download.IDownloadData; import com.teleca.jamendo.util.download.DownloadHelper; import com.teleca.jamendo.util.download.IDownload; import com.teleca.jamendo.util.download.DownloadJob; /** * Singleton with hooks to Player and Download Service * * @author Lukasz Wisniewski */ public class MyApplication extends Application { /** * Tag used for DDMS logging */ public static String TAG = "jamendo"; /** * Singleton pattern */ private static MyApplication instance; /** * Image cache, one for all activities and orientations */ private ImgCache mImageCache; /** * Web request cache, one for all activities and orientations */ private RequestCache mRequestCache; /** * Service player engine */ private IPlayEngine mServicePlayerEngine; /** * Intent player engine */ private IPlayEngine mIntentPlayerEngine; /** * Player engine listener */ private IPlayEngineListener mPlayerEngineListener; /** * Download interface */ private IDownload mDownloadInterface; /** * Stored in Application instance in case we destory Player service */ private PlayMethod mPlaylist; /** * Stores info about this session's finished downloads */ private ArrayList<DownloadJob> mCompletedDownloads; /** * Stores info about this session's downloads that are queued */ private ArrayList<DownloadJob> mQueuedDownloads; public static MyApplication getInstance() { return instance; } @Override public void onCreate() { super.onCreate(); mImageCache = new ImgCache(); mRequestCache = new RequestCache(); Caller.setRequestCache(mRequestCache); instance = this; mQueuedDownloads = new ArrayList<DownloadJob>(); mCompletedDownloads = new ArrayList<DownloadJob>(); } /** * Access to global image cache across Activity instances * * @return */ public ImgCache getImageCache() { return mImageCache; } /** * This setter should be only used for setting real player engine interface, * e.g. used to pass Player Service's engine * * @param playerEngine */ public void setConcretePlayerEngine(IPlayEngine playerEngine) { this.mServicePlayerEngine = playerEngine; } /** * This getter allows performing logical operations on the player engine's * interface from UI space * * @return */ public IPlayEngine getPlayerEngineInterface() { // request service bind if (mIntentPlayerEngine == null) { mIntentPlayerEngine = new IntentPlayerEngine(); } return mIntentPlayerEngine; } /** * This function allows to add listener to the concrete player engine * * @param l */ public void setPlayerEngineListener(IPlayEngineListener l) { getPlayerEngineInterface().setListener(l); } /** * This function is used by PlayerService on ACTION_BIND_LISTENER in order * to get to Application's exposed listener. * * @return */ public IPlayEngineListener fetchPlayerEngineListener() { return mPlayerEngineListener; } /** * Returns current playlist, used in PlayerSerive in onStart method * * @return */ public PlayMethod fetchPlaylist() { return mPlaylist; } // 获取程序的版本号 public String getVersion() { String version = "0.0.0"; PackageManager packageManager = getPackageManager(); try { PackageInfo packageInfo = packageManager.getPackageInfo( getPackageName(), 0); version = packageInfo.versionName; } catch (NameNotFoundException e) { e.printStackTrace(); } return version; } public void setDownloadInterface(IDownload downloadInterface) { mDownloadInterface = downloadInterface; } public IDownload getDownloadInterface() { if (mDownloadInterface == null) { mDownloadInterface = new IntentDownloadInterface(); } return mDownloadInterface; } public void setQueuedDownloads(ArrayList<DownloadJob> mQueuedDownloads) { this.mQueuedDownloads = mQueuedDownloads; } public ArrayList<DownloadJob> getQueuedDownloads() { return mQueuedDownloads; } public void setCompletedDownloads(ArrayList<DownloadJob> mCompletedDownloads) { this.mCompletedDownloads = mCompletedDownloads; } public ArrayList<DownloadJob> getCompletedDownloads() { return mCompletedDownloads; } /** * Since 0.9.8.7 we embrace "bindless" PlayerService thus this adapter. No * big need of code refactoring, we just wrap sending intents around defined * interface * * @author Lukasz Wisniewski */ private class IntentPlayerEngine implements IPlayEngine { @Override public PlayMethod getPlaylist() { return mPlaylist; } @Override public boolean isPlaying() { if (mServicePlayerEngine == null) { // service does not exist thus no playback possible return false; } else { return mServicePlayerEngine.isPlaying(); } } @Override public void next() { if (mServicePlayerEngine != null) { playlistCheck(); mServicePlayerEngine.next(); } else { startAction(PlayerService.ACTION_NEXT); } } @Override public void openPlaylist(PlayMethod playlist) { mPlaylist = playlist; if (mServicePlayerEngine != null) { mServicePlayerEngine.openPlaylist(playlist); } } @Override public void pause() { if (mServicePlayerEngine != null) { mServicePlayerEngine.pause(); } } @Override public void play() { if (mServicePlayerEngine != null) { playlistCheck(); mServicePlayerEngine.play(); } else { startAction(PlayerService.ACTION_PLAY); } } @Override public void prev() { if (mServicePlayerEngine != null) { playlistCheck(); mServicePlayerEngine.prev(); } else { startAction(PlayerService.ACTION_PREV); } } @Override public void setListener(IPlayEngineListener playerEngineListener) { mPlayerEngineListener = playerEngineListener; // we do not want to set this listener if Service // is not up and a new listener is null if (mServicePlayerEngine != null || mPlayerEngineListener != null) { startAction(PlayerService.ACTION_BIND_LISTENER); } } @Override public void skipTo(int index) { if (mServicePlayerEngine != null) { mServicePlayerEngine.skipTo(index); } } @Override public void stop() { startAction(PlayerService.ACTION_STOP); // stopService(new Intent(JamendoApplication.this, // PlayerService.class)); } private void startAction(String action) { Intent intent = new Intent(MyApplication.this, PlayerService.class); intent.setAction(action); startService(intent); } /** * This is required if Player Service was binded but playlist was not * passed from Application to Service and one of buttons: play, next, * prev is pressed */ private void playlistCheck() { if (mServicePlayerEngine != null) { if (mServicePlayerEngine.getPlaylist() == null && mPlaylist != null) { mServicePlayerEngine.openPlaylist(mPlaylist); } } } } private class IntentDownloadInterface implements IDownload { @Override public void addToDownloadQueue(Playlist entry) { Intent intent = new Intent(MyApplication.this, DownloadService.class); intent.setAction(DownloadService.ACTION_ADD_TO_DOWNLOAD); intent.putExtra(DownloadService.EXTRA_PLAYLIST_ENTRY, entry); startService(intent); } @Override public ArrayList<DownloadJob> getAllDownloads() { ArrayList<DownloadJob> allDownloads = new ArrayList<DownloadJob>(); allDownloads.addAll(mCompletedDownloads); allDownloads.addAll(mQueuedDownloads); return allDownloads; } @Override public ArrayList<DownloadJob> getCompletedDownloads() { return mCompletedDownloads; } @Override public ArrayList<DownloadJob> getQueuedDownloads() { return mQueuedDownloads; } @Override public String getTrackPath(Playlist entry) { if (entry == null) { return null; } if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // we need to check the database to be sure whether file was // downloaded completely IDownloadData downloadDatabase = DownloadService .getDownloadDatabase(); if (downloadDatabase != null) { if (!downloadDatabase.trackAvailable(entry.getTrack())) return null; } // now we may give a reference to this file after we check it // really exists // in case file was somehow removed manually String trackPath = DownloadHelper.getAbsolutePath(entry, DownloadService.getDownloadPath()); String fileNameMP3 = DownloadHelper.getFileName(entry, IServerApi.ENCODING_MP3); File fileMP3 = new File(trackPath, fileNameMP3); if (fileMP3.exists()) { String path = fileMP3.getAbsolutePath(); Log.i(TAG, "Playing from local file: " + fileMP3); return path; } String fileNameOGG = DownloadHelper.getFileName(entry, IServerApi.ENCODING_OGG); File fileOGG = new File(trackPath, fileNameOGG); if (fileOGG.exists()) { String path = fileOGG.getAbsolutePath(); Log.i(TAG, "Playing from local file: " + fileOGG); return path; } } return null; } } public String getDownloadFormat() { return PreferenceManager.getDefaultSharedPreferences(this).getString( "download_format", IServerApi.ENCODING_MP3); } public String getStreamEncoding() { // http://groups.google.com/group/android-developers/msg/c546760177b22197 // According to JBQ: ogg files are supported but not streamable return IServerApi.ENCODING_MP3; } }