Overhauled repository update to resolve multiple problems
This commit is contained in:
parent
7647cc2594
commit
c98aa9f6dc
@ -200,7 +200,6 @@ public class AppDetails extends ListActivity {
|
|||||||
db = new DB(this);
|
db = new DB(this);
|
||||||
compatChecker = db.getCompatibilityChecker();
|
compatChecker = db.getCompatibilityChecker();
|
||||||
mPm = getPackageManager();
|
mPm = getPackageManager();
|
||||||
((FDroidApp) getApplication()).inActivity++;
|
|
||||||
// Get the preferences we're going to use in this Activity...
|
// Get the preferences we're going to use in this Activity...
|
||||||
SharedPreferences prefs = PreferenceManager
|
SharedPreferences prefs = PreferenceManager
|
||||||
.getDefaultSharedPreferences(getBaseContext());
|
.getDefaultSharedPreferences(getBaseContext());
|
||||||
@ -238,7 +237,6 @@ public class AppDetails extends ListActivity {
|
|||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
db.close();
|
db.close();
|
||||||
db = null;
|
db = null;
|
||||||
((FDroidApp) getApplication()).inActivity--;
|
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import android.app.AlertDialog;
|
|||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.app.TabActivity;
|
import android.app.TabActivity;
|
||||||
import android.app.AlertDialog.Builder;
|
import android.app.AlertDialog.Builder;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
@ -39,6 +40,7 @@ import android.net.Uri;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.ResultReceiver;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@ -135,7 +137,6 @@ public class FDroid extends TabActivity implements OnItemClickListener,
|
|||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
((FDroidApp) getApplication()).inActivity++;
|
|
||||||
db = new DB(this);
|
db = new DB(this);
|
||||||
triedEmptyUpdate = false;
|
triedEmptyUpdate = false;
|
||||||
populateLists(true);
|
populateLists(true);
|
||||||
@ -144,7 +145,6 @@ public class FDroid extends TabActivity implements OnItemClickListener,
|
|||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
db.close();
|
db.close();
|
||||||
((FDroidApp) getApplication()).inActivity--;
|
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,26 +415,15 @@ public class FDroid extends TabActivity implements OnItemClickListener,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRepos() {
|
// For receiving results from the UpdateService when we've told it to
|
||||||
pd = ProgressDialog.show(this, getString(R.string.process_wait_title),
|
// update in response to a user request.
|
||||||
getString(R.string.process_update_msg), true);
|
private class UpdateReceiver extends ResultReceiver {
|
||||||
pd.setIcon(android.R.drawable.ic_dialog_info);
|
public UpdateReceiver(Handler handler) {
|
||||||
|
super(handler);
|
||||||
new Thread() {
|
}
|
||||||
public void run() {
|
|
||||||
boolean success = RepoXMLHandler.doUpdates(FDroid.this, db);
|
|
||||||
update_handler.sendEmptyMessage(success ? 0 : 1);
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handlers for thread functions that need to access GUI
|
|
||||||
*/
|
|
||||||
private Handler update_handler = new Handler() {
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
protected void onReceiveResult (int resultCode, Bundle resultData) {
|
||||||
if (msg.what == 1) {
|
if (resultCode == 1) {
|
||||||
Toast.makeText(FDroid.this,
|
Toast.makeText(FDroid.this,
|
||||||
getString(R.string.connection_error_msg),
|
getString(R.string.connection_error_msg),
|
||||||
Toast.LENGTH_LONG).show();
|
Toast.LENGTH_LONG).show();
|
||||||
@ -444,7 +433,22 @@ public class FDroid extends TabActivity implements OnItemClickListener,
|
|||||||
if (pd.isShowing())
|
if (pd.isShowing())
|
||||||
pd.dismiss();
|
pd.dismiss();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
private UpdateReceiver mUpdateReceiver;
|
||||||
|
|
||||||
|
// Force a repo update now. A progress dialog is shown and the UpdateService
|
||||||
|
// is told to do the update, which will result in the database changing. The
|
||||||
|
// UpdateReceiver class should get told when this is finished.
|
||||||
|
private void updateRepos() {
|
||||||
|
pd = ProgressDialog.show(this, getString(R.string.process_wait_title),
|
||||||
|
getString(R.string.process_update_msg), true, true);
|
||||||
|
pd.setIcon(android.R.drawable.ic_dialog_info);
|
||||||
|
|
||||||
|
Intent intent = new Intent(this, UpdateService.class);
|
||||||
|
mUpdateReceiver = new UpdateReceiver(new Handler());
|
||||||
|
intent.putExtra("receiver", mUpdateReceiver);
|
||||||
|
startService(intent);
|
||||||
|
}
|
||||||
|
|
||||||
public void onItemSelected(AdapterView<?> parent, View view, int pos,
|
public void onItemSelected(AdapterView<?> parent, View view, int pos,
|
||||||
long id) {
|
long id) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 Ciaran Gultnieks, ciaran@ciarang.com
|
* Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -22,10 +22,5 @@ import android.app.Application;
|
|||||||
|
|
||||||
public class FDroidApp extends Application {
|
public class FDroidApp extends Application {
|
||||||
|
|
||||||
// Keeps track of when we are in one of our activities where we
|
|
||||||
// don't want a database update to run. Incremented when entering
|
|
||||||
// one, and decremented when leaving, so if it's 0 it ought to be
|
|
||||||
// ok!
|
|
||||||
public int inActivity = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 Ciaran Gultnieks, ciaran@ciarang.com
|
* Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -19,6 +19,7 @@
|
|||||||
package org.fdroid.fdroid;
|
package org.fdroid.fdroid;
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
|
import android.app.IntentService;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@ -26,12 +27,19 @@ import android.app.Service;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.ResultReceiver;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class UpdateService extends Service {
|
public class UpdateService extends IntentService {
|
||||||
|
|
||||||
|
public UpdateService() {
|
||||||
|
super("UpdateService");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Schedule (or cancel schedule for) this service, according to the
|
// Schedule (or cancel schedule for) this service, according to the
|
||||||
// current preferences. Should be called a) at boot, or b) if the preference
|
// current preferences. Should be called a) at boot, or b) if the preference
|
||||||
@ -55,103 +63,89 @@ public class UpdateService extends Service {
|
|||||||
SystemClock.elapsedRealtime() + 5000,
|
SystemClock.elapsedRealtime() + 5000,
|
||||||
AlarmManager.INTERVAL_HOUR, pending);
|
AlarmManager.INTERVAL_HOUR, pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For API levels <5
|
|
||||||
@Override
|
|
||||||
public void onStart(Intent intent, int startId) {
|
|
||||||
handleCommand();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For API levels >=5
|
protected void onHandleIntent(Intent intent) {
|
||||||
@Override
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
handleCommand();
|
|
||||||
return START_REDELIVER_INTENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleCommand() {
|
// We might be doing a scheduled run, or we might have been launched by
|
||||||
|
// the app in response to a user's request. If we get this receiver, it's
|
||||||
|
// the latter...
|
||||||
|
ResultReceiver receiver = intent.getParcelableExtra("receiver");
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager
|
||||||
|
.getDefaultSharedPreferences(getBaseContext());
|
||||||
|
|
||||||
new Thread() {
|
// See if it's time to actually do anything yet...
|
||||||
public void run() {
|
if(receiver == null) {
|
||||||
|
long lastUpdate = prefs.getLong("lastUpdateCheck", 0);
|
||||||
|
String sint = prefs.getString("updateInterval", "0");
|
||||||
|
int interval = Integer.parseInt(sint);
|
||||||
|
if (interval == 0)
|
||||||
|
return;
|
||||||
|
if (lastUpdate + (interval * 60 * 60) > System
|
||||||
|
.currentTimeMillis())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we're in one of our list activities, we don't want
|
// Do the update...
|
||||||
// to run an update because the database will be out of
|
DB db = null;
|
||||||
// sync with the display.
|
try {
|
||||||
if (((FDroidApp) getApplication()).inActivity != 0)
|
db = new DB(getBaseContext());
|
||||||
return;
|
boolean notify = prefs.getBoolean("updateNotify", false);
|
||||||
|
|
||||||
// See if it's time to actually do anything yet...
|
// Get the number of updates available before we
|
||||||
SharedPreferences prefs = PreferenceManager
|
// start, so we can notify if there are new ones.
|
||||||
.getDefaultSharedPreferences(getBaseContext());
|
// (But avoid doing it if the user doesn't want
|
||||||
long lastUpdate = prefs.getLong("lastUpdateCheck", 0);
|
// notifications, since it may be time consuming)
|
||||||
String sint = prefs.getString("updateInterval", "0");
|
int prevUpdates = 0;
|
||||||
int interval = Integer.parseInt(sint);
|
if (notify)
|
||||||
if (interval == 0)
|
prevUpdates = db.getNumUpdates();
|
||||||
return;
|
|
||||||
if (lastUpdate + (interval * 60 * 60) > System
|
|
||||||
.currentTimeMillis())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Do the update...
|
boolean success = RepoXMLHandler.doUpdates(
|
||||||
DB db = null;
|
getBaseContext(), db);
|
||||||
try {
|
|
||||||
db = new DB(getBaseContext());
|
|
||||||
boolean notify = prefs.getBoolean("updateNotify", false);
|
|
||||||
|
|
||||||
// Get the number of updates available before we
|
if (success && notify) {
|
||||||
// start, so we can notify if there are new ones.
|
int newUpdates = db.getNumUpdates();
|
||||||
// (But avoid doing it if the user doesn't want
|
Log.d("FDroid", "Updates before:" + prevUpdates + ", after: " +newUpdates);
|
||||||
// notifications, since it may be time consuming)
|
if (newUpdates > prevUpdates) {
|
||||||
int prevUpdates = 0;
|
NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
if (notify)
|
Notification notification = new Notification(
|
||||||
prevUpdates = db.getNumUpdates();
|
R.drawable.icon,
|
||||||
|
"FDroid Updates Available", System
|
||||||
boolean success = RepoXMLHandler.doUpdates(
|
.currentTimeMillis());
|
||||||
getBaseContext(), db);
|
Context context = getApplicationContext();
|
||||||
|
CharSequence contentTitle = "FDroid";
|
||||||
if (success && notify) {
|
CharSequence contentText = "Updates are available.";
|
||||||
int newUpdates = db.getNumUpdates();
|
Intent notificationIntent = new Intent(
|
||||||
Log.d("FDroid", "Updates before:" + prevUpdates + ", after: " +newUpdates);
|
UpdateService.this, FDroid.class);
|
||||||
if (newUpdates > prevUpdates) {
|
PendingIntent contentIntent = PendingIntent
|
||||||
NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
.getActivity(UpdateService.this, 0,
|
||||||
Notification notification = new Notification(
|
notificationIntent, 0);
|
||||||
R.drawable.icon,
|
notification.setLatestEventInfo(context,
|
||||||
"FDroid Updates Available", System
|
contentTitle, contentText, contentIntent);
|
||||||
.currentTimeMillis());
|
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||||
Context context = getApplicationContext();
|
n.notify(1, notification);
|
||||||
CharSequence contentTitle = "FDroid";
|
|
||||||
CharSequence contentText = "Updates are available.";
|
|
||||||
Intent notificationIntent = new Intent(
|
|
||||||
UpdateService.this, FDroid.class);
|
|
||||||
PendingIntent contentIntent = PendingIntent
|
|
||||||
.getActivity(UpdateService.this, 0,
|
|
||||||
notificationIntent, 0);
|
|
||||||
notification.setLatestEventInfo(context,
|
|
||||||
contentTitle, contentText, contentIntent);
|
|
||||||
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
|
||||||
n.notify(1, notification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("FDroid", "Exception during handleCommand():\n"
|
|
||||||
+ Log.getStackTraceString(e));
|
|
||||||
} finally {
|
|
||||||
if (db != null)
|
|
||||||
db.close();
|
|
||||||
stopSelf();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}.start();
|
|
||||||
|
if(receiver != null) {
|
||||||
|
Bundle resultData = new Bundle();
|
||||||
|
receiver.send(0, resultData);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
|
Log.e("FDroid", "Exception during handleCommand():\n"
|
||||||
|
+ Log.getStackTraceString(e));
|
||||||
|
if(receiver != null) {
|
||||||
|
Bundle resultData = new Bundle();
|
||||||
|
receiver.send(1, resultData);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (db != null)
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder onBind(Intent intent) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user