/***************************************************************************
* Copyright 2005-2009 Last.fm Ltd. *
* Portions contributed by Casey Link, Lukasz Wisniewski, *
* Mike Jennings, and Michael Novak Jr. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
package fm.last.android;
import java.util.Locale;
import android.app.AlertDialog;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import fm.last.android.activity.Player;
import fm.last.android.db.LastFmDbHelper;
import fm.last.android.player.IRadioPlayer;
import fm.last.android.player.RadioPlayerService;
import fm.last.android.sync.AccountAuthenticatorService;
import fm.last.api.Session;
import fm.last.api.WSError;
import fm.last.util.UrlUtil;
public class LastFMApplication extends Application {
public Session session;
public fm.last.android.player.IRadioPlayer player = null;
public Context mCtx;
public GoogleAnalyticsTracker tracker;
private String mRequestedURL;
private static LastFMApplication instance = null;
public static LastFMApplication getInstance() {
if(instance != null) {
return instance;
} else {
return new LastFMApplication();
}
}
@Override
public void onCreate() {
super.onCreate();
instance = this;
String version;
try {
version = "/" + LastFMApplication.getInstance().getPackageManager().getPackageInfo("fm.last.android", 0).versionName;
} catch (Exception e) {
version = "";
}
UrlUtil.useragent = "MobileLastFM" + version + " (" + android.os.Build.MODEL + "; " + Locale.getDefault().getCountry().toLowerCase() + "; "
+ "Android " + android.os.Build.VERSION.RELEASE + ")";
// Populate our Session object
SharedPreferences settings = getSharedPreferences(LastFm.PREFS, 0);
String username = settings.getString("lastfm_user", "");
String session_key = settings.getString("lastfm_session_key", "");
String subscriber = settings.getString("lastfm_subscriber", "0");
session = new Session(username, session_key, subscriber);
tracker = GoogleAnalyticsTracker.getInstance();
tracker.start(PrivateAPIKey.ANALYTICS_ID, this);
version = "0.1";
try {
version = getPackageManager().getPackageInfo("fm.last.android", 0).versionName;
} catch (NameNotFoundException e) {
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
player = fm.last.android.player.IRadioPlayer.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className) {
player = null;
}
};
public void bindPlayerService() {
// start our media player service
Intent mpIntent = new Intent(this, fm.last.android.player.RadioPlayerService.class);
boolean b = bindService(mpIntent, mConnection, BIND_AUTO_CREATE);
if (!b) {
// something went wrong
// mHandler.sendEmptyMessage(QUIT);
System.out.println("Binding to service failed " + mConnection);
}
}
public void unbindPlayerService() {
try {
if(player != null && player.asBinder().isBinderAlive())
unbindService(mConnection);
} catch (Exception e) {
}
player = null;
}
public void playRadioStation(Context ctx, String url, boolean showPlayer) {
mCtx = ctx;
mRequestedURL = url;
Log.i("Last.fm", "Free trial active: " + getSharedPreferences(LastFm.PREFS, 0).getBoolean("lastfm_freetrial", false));
Log.i("Last.fm", "Free trial plays elapsed: " + getSharedPreferences(LastFm.PREFS, 0).getInt("lastfm_playselapsed", 0));
Log.i("Last.fm", "Free trial plays remaining: " + getSharedPreferences(LastFm.PREFS, 0).getInt("lastfm_playsleft", 30));
if (getSharedPreferences(LastFm.PREFS, 0).getBoolean("lastfm_freetrial", false) && getSharedPreferences(LastFm.PREFS, 0).getInt("lastfm_playselapsed", 0) == 0) {
AlertDialog.Builder d = new AlertDialog.Builder(ctx);
d.setTitle("Start Free Trial");
d.setMessage("Radio is a subscriber only feature. Try it now with a free " + getSharedPreferences(LastFm.PREFS, 0).getInt("lastfm_playsleft", 30) + " track trial.");
d.setIcon(android.R.drawable.ic_dialog_info);
d.setPositiveButton("Start Trial", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
SharedPreferences.Editor editor = getSharedPreferences(LastFm.PREFS, 0).edit();
editor.putInt("lastfm_playselapsed", 1);
editor.commit();
playRadioStation(mCtx, mRequestedURL, true);
}
});
d.setNegativeButton("Later", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//Clear the loading indicators
sendBroadcast(new Intent("fm.last.android.ERROR"));
}
});
try {
d.show();
} catch (Exception e) { //If the app isn't currently on-screen, bring it forward and try again
Intent intent = new Intent ( Intent.ACTION_VIEW, Uri.parse(mRequestedURL));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity( intent );
}
} else if (session != null && session.getKey().length() > 0) {
final Intent out = new Intent(this, RadioPlayerService.class);
out.setAction("fm.last.android.PLAY");
out.putExtra("station", url);
out.putExtra("session", (Parcelable) session);
startService(out);
if (showPlayer) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RadioPlayerService.STATION_CHANGED);
intentFilter.addAction("fm.last.android.ERROR");
BroadcastReceiver statusListener = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
unregisterReceiver(this);
} catch (Exception e) {
e.printStackTrace(); //Sometimes this can throw an IllegalArgumentException
}
String action = intent.getAction();
if (action.equals(RadioPlayerService.STATION_CHANGED)) {
Intent i = new Intent(LastFMApplication.this, Player.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
} else if (action.equals("fm.last.android.ERROR")) {
WSError e = intent.getParcelableExtra("error");
if(e != null) {
Log.e("Last.fm", "Tuning error: " + e.getMessage());
}
presentError(mCtx, e);
}
}
};
registerReceiver(statusListener, intentFilter);
}
} else {
Intent i = new Intent(mCtx, LastFm.class);
i.putExtra("station", url);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mCtx.startActivity(i);
}
}
@Override
public void onTerminate() {
session = null;
instance = null;
tracker.stop();
super.onTerminate();
}
public void presentError(Context ctx, WSError error) {
int title = 0;
int description = 0;
if(error != null) {
Log.e("Last.fm", "Received a webservice error during method: " + error.getMethod() + ", message: " + error.getMessage());
try {
LastFMApplication.getInstance().tracker.trackEvent("Errors", // Category
error.getMethod(), // Action
error.getMessage(), // Label
0); // Value
} catch (Exception e) {
//Google Analytics doesn't appear to be thread safe
}
if (error.getMethod().startsWith("radio.")) {
title = R.string.ERROR_STATION_TITLE;
switch (error.getCode()) {
case WSError.ERROR_NotEnoughContent:
title = R.string.ERROR_INSUFFICIENT_CONTENT_TITLE;
description = R.string.ERROR_INSUFFICIENT_CONTENT;
break;
case WSError.ERROR_NotEnoughFans:
description = R.string.ERROR_INSUFFICIENT_FANS;
break;
case WSError.ERROR_NotEnoughMembers:
description = R.string.ERROR_INSUFFICIENT_MEMBERS;
break;
case WSError.ERROR_NotEnoughNeighbours:
description = R.string.ERROR_INSUFFICIENT_NEIGHBOURS;
break;
case WSError.ERROR_RadioUnavailable:
case WSError.ERROR_AuthenticationFailed:
case WSError.ERROR_GeoRestricted:
description = R.string.ERROR_RADIO_UNAVAILABLE;
break;
case WSError.ERROR_TrialExpired:
title = R.string.ERROR_TRIAL_EXPIRED_TITLE;
description = R.string.ERROR_TRIAL_EXPIRED;
AlertDialog.Builder d = new AlertDialog.Builder(ctx);
d.setTitle(getResources().getString(title));
d.setMessage(getResources().getString(description));
d.setIcon(android.R.drawable.ic_dialog_alert);
d.setPositiveButton("Subscribe", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("http://www.last.fm/subscribe"));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
});
d.setNegativeButton("Later", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
try {
d.show();
} catch (Exception e) {
}
return;
case WSError.ERROR_Deprecated:
title = R.string.ERROR_DEPRECATED_TITLE;
SharedPreferences settings = getSharedPreferences(LastFm.PREFS, 0);
SharedPreferences.Editor editor = settings.edit();
if(mRequestedURL.startsWith("lastfm://playlist/")) {
description = R.string.ERROR_DEPRECATED_PLAYLISTS;
editor.putBoolean("remove_playlists", true);
}
if(mRequestedURL.startsWith("lastfm://usertags/")) {
description = R.string.ERROR_DEPRECATED_TAGS;
editor.putBoolean("remove_tags", true);
}
if(mRequestedURL.endsWith("/loved")) {
description = R.string.ERROR_DEPRECATED_LOVED;
editor.putBoolean("remove_loved", true);
}
editor.commit();
Intent i = new Intent(RadioPlayerService.STATION_CHANGED);
sendBroadcast(i);
break;
}
}
if (error.getMethod().equals("user.signUp")) {
title = R.string.ERROR_SIGNUP_TITLE;
switch (error.getCode()) {
case WSError.ERROR_InvalidParameters:
presentError(ctx, getResources().getString(title), error.getMessage());
return;
}
}
}
if (title == 0)
title = R.string.ERROR_SERVER_UNAVAILABLE_TITLE;
if (description == 0) {
if(error != null) {
switch (error.getCode()) {
case WSError.ERROR_AuthenticationFailed:
case WSError.ERROR_InvalidSession:
title = R.string.ERROR_SESSION_TITLE;
description = R.string.ERROR_SESSION;
break;
case WSError.ERROR_InvalidAPIKey:
title = R.string.ERROR_UPGRADE_TITLE;
description = R.string.ERROR_UPGRADE;
break;
case WSError.ERROR_SubscribersOnly:
title = R.string.ERROR_SUBSCRIPTION_TITLE;
description = R.string.ERROR_SUBSCRIPTION;
break;
default:
presentError(ctx, getResources().getString(title), getResources().getString(R.string.ERROR_SERVER_UNAVAILABLE) + "\n\n" + error.getMethod() + ": " + error.getMessage());
return;
}
} else {
description = R.string.ERROR_SERVER_UNAVAILABLE;
}
}
presentError(ctx, getResources().getString(title), getResources().getString(description));
}
public void presentError(Context ctx, String title, String description) {
AlertDialog.Builder d = new AlertDialog.Builder(ctx);
d.setTitle(title);
d.setMessage(description);
d.setIcon(android.R.drawable.ic_dialog_alert);
d.setNeutralButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
try {
d.show();
} catch (Exception e) {
Intent intent = new Intent(LastFMApplication.this, Player.class);
intent.putExtra("ERROR_TITLE", title);
intent.putExtra("ERROR_DESCRIPTION", description);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
public void logout() {
SharedPreferences settings = getSharedPreferences(LastFm.PREFS, 0);
SharedPreferences.Editor editor = settings.edit();
editor.remove("lastfm_user");
editor.remove("lastfm_pass");
editor.remove("lastfm_session_key");
editor.remove("lastfm_subscriber");
editor.remove("lastfm_freetrial");
editor.remove("lastfm_radio");
editor.remove("lastfm_playselapsed");
editor.remove("lastfm_playsremaining");
editor.remove("lastfm_freetrialexpirationwarning");
editor.remove("scrobbler_session");
editor.remove("scrobbler_subsurl");
editor.remove("scrobbler_npurl");
editor.commit();
session = null;
try {
LastFMApplication.getInstance().bindService(new Intent(this, fm.last.android.player.RadioPlayerService.class), new ServiceConnection() {
public void onServiceConnected(ComponentName comp, IBinder binder) {
IRadioPlayer player = IRadioPlayer.Stub.asInterface(binder);
try {
if (player.isPlaying())
player.stop();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
LastFMApplication.getInstance().unbindService(this);
} catch (IllegalArgumentException e) {
}
}
public void onServiceDisconnected(ComponentName comp) {
}
}, 0);
LastFmDbHelper.getInstance().clearDatabase();
if(Integer.decode(Build.VERSION.SDK) >= 6) {
AccountAuthenticatorService.removeLastfmAccount(this);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}