/*******************************************************************************
* Copyright (c) 2011 Jordan Thoms.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package biz.shadowservices.DegreesToolbox;
import java.io.IOException;
import java.util.Date;
import org.apache.http.client.ClientProtocolException;
import biz.shadowservices.DegreesToolbox.DataFetcher.FetchResult;
import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import de.quist.app.errorreporter.ReportingService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Binder;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
public class UpdateWidgetService extends ReportingService implements Runnable {
// This is the service which handles updating the widgets.
private static String TAG = "2DegreesUpdateWidgetService";
public static String NEWDATA = "BalanceWidgetNewDataAvailable12";
/**
* Flag if there is an update thread already running. We only launch a new
* thread if one isn't already running.
*/
private static boolean isThreadRunning = false;
private static Object lock = new Object();
private boolean force = false;
public class LocalBinder extends Binder {
UpdateWidgetService getService() {
return UpdateWidgetService.this;
}
}
private final IBinder mBinder = new LocalBinder();
static {
// Populate the list of widget updaters - in a static initaliser block since it only needs
// to happen once.
Values.widgetUpdaters.add(new WidgetUpdater1x2());
Values.widgetUpdaters.add(new WidgetUpdater2x2());
}
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
@Override
public void onStart(Intent intent, int startId) {
handleCommand(intent);
}
public int onStartCommand(Intent intent, int startId) {
handleCommand(intent);
return START_NOT_STICKY;
}
private void handleCommand(Intent intent) {
Log.d(TAG, "Starting service");
if (intent != null) {
force = intent.getBooleanExtra("biz.shadowservices.PhoneBalanceWidget.forceUpdates", false);
}
// Locking to make sure we only run one thread at a time.
synchronized (lock) {
if(!isThreadRunning) {
Log.d(TAG, "Thread not running, starting.");
isThreadRunning = true;
new Thread(this).start();
} else {
Log.d(TAG, "Thread already running, not doing anything.");
}
}
}
@Override
public void run() {
//Build update
Log.d(TAG, "Building updates");
for (AbstractWidgetUpdater updater : Values.widgetUpdaters) {
updater.widgetLoading(this);
}
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
String updateDateString = sp.getString("updateDate", "");
boolean update = true;
if (!force) {
try {
Date now = new Date();
Date lastUpdate = DateFormatters.ISO8601FORMAT.parse(updateDateString);
long diff = now.getTime() - lastUpdate.getTime();
long mins = diff / (1000 * 60);
if (mins < Integer.parseInt(sp.getString("freshTime", "30"))) {
update = false;
}
} catch (Exception e) {
Log.d(TAG, "Failed when deciding whether to update");
}
}
DataFetcher dataFetcher = new DataFetcher(getExceptionReporter());
FetchResult result = null;
if(update) {
result = dataFetcher.updateData(this, force);
// Login failed - set error for the activity so it can display the information
Editor edit = sp.edit();
edit.putString("updateStatus", result.toString());
edit.commit();
Log.d(TAG, "Building updates -- data updated. Result: " + result.toString());
} else {
Log.d(TAG, "Building updates -- data fresh, not updated");
result = FetchResult.SUCCESS;
}
for (AbstractWidgetUpdater updater : Values.widgetUpdaters) {
updater.updateWidgets(this, force, result);
}
Log.d(TAG, "Sent updates");
Intent myIntent = new Intent(NEWDATA);
sendBroadcast(myIntent);
// We now dispatch to GA.
// Wrap up in a catch all since this has been having problems
try {
GATracker.getInstance(getApplication()).incrementActivityCount();
GATracker.getInstance().dispatch();
GATracker.getInstance().decrementActivityCount();
} catch (Exception e) {
getExceptionReporter().reportException(Thread.currentThread(), e, "GA Tracking in updateWidgetService");
}
isThreadRunning = false;
// Stop the service. A lot of apps leave their widget update services running, which is completely unnecessary!
stopSelf();
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}