diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f9782bf9d..519f2504e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,9 +15,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java
index 83069f7a2..888bce4c4 100644
--- a/src/org/fdroid/fdroid/DB.java
+++ b/src/org/fdroid/fdroid/DB.java
@@ -404,6 +404,8 @@ public class DB {
// have 'updated' set to false at this point, and we will only set
// it to true when we see the app/apk in a repository. Thus, at the
// end, any that are still false can be removed.
+ // TODO: Need to ensure that UI and UpdateService can't both be doing
+ // an update at the same time.
updateApps = getApps(null, null, true);
Log.d("FDroid", "AppUpdate: " + updateApps.size()
+ " apps before starting.");
diff --git a/src/org/fdroid/fdroid/FDroid.java b/src/org/fdroid/fdroid/FDroid.java
index ff1fde03f..fd0d8c482 100644
--- a/src/org/fdroid/fdroid/FDroid.java
+++ b/src/org/fdroid/fdroid/FDroid.java
@@ -19,27 +19,11 @@
package org.fdroid.fdroid;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-
import org.fdroid.fdroid.R;
import android.R.drawable;
@@ -144,7 +128,6 @@ public class FDroid extends TabActivity implements OnItemClickListener {
}
private String LOCAL_PATH = "/sdcard/.fdroid";
- private String XML_PATH = LOCAL_PATH + "/remapklst.xml";
private static final int REQUEST_APPDETAILS = 0;
private static final int REQUEST_MANAGEREPOS = 1;
@@ -168,8 +151,6 @@ public class FDroid extends TabActivity implements OnItemClickListener {
private ProgressDialog pd;
- private Context mctx = this;
-
private static final String TAB_IN = "INST";
private static final String TAB_UN = "UNIN";
private static final String TAB_UP = "UPDT";
@@ -405,20 +386,7 @@ public class FDroid extends TabActivity implements OnItemClickListener {
|| netstate.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED) {
new Thread() {
public void run() {
- try {
- db.beginUpdate();
- Vector repos = db.getRepos();
- for (DB.Repo repo : repos) {
- if (repo.inuse) {
- downloadRepoIndex(repo.address);
- xmlPass(repo.address);
- }
- }
- db.endUpdate();
- } catch (Exception e) {
- Log.d("FDroid", "Exception while updating - "
- + e.getMessage());
- }
+ RepoXMLHandler.doUpdates(db);
update_handler.sendEmptyMessage(0);
}
}.start();
@@ -431,60 +399,6 @@ public class FDroid extends TabActivity implements OnItemClickListener {
}
}
- /*
- * Pass XML info to BD a xml file must exists...
- */
- private void xmlPass(String srv) {
- SAXParserFactory spf = SAXParserFactory.newInstance();
- try {
- SAXParser sp = spf.newSAXParser();
- XMLReader xr = sp.getXMLReader();
- RepoXMLHandler handler = new RepoXMLHandler(this, srv, db);
- xr.setContentHandler(handler);
-
- InputStreamReader isr = new FileReader(new File(XML_PATH));
- InputSource is = new InputSource(isr);
- xr.parse(is);
- File xml_file = new File(XML_PATH);
- xml_file.delete();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- }
- }
-
- // Download a repo index to a temporary file on the SD card.
- private void downloadRepoIndex(String srv) {
- try {
- BufferedInputStream getit = new BufferedInputStream(new URL(srv
- + "/index.xml").openStream());
-
- File file_teste = new File(XML_PATH);
- if (file_teste.exists())
- file_teste.delete();
-
- FileOutputStream saveit = new FileOutputStream(XML_PATH);
- BufferedOutputStream bout = new BufferedOutputStream(saveit, 1024);
- byte data[] = new byte[1024];
-
- int readed = getit.read(data, 0, 1024);
- while (readed != -1) {
- bout.write(data, 0, readed);
- readed = getit.read(data, 0, 1024);
- }
- bout.close();
- getit.close();
- saveit.close();
- } catch (UnknownHostException e) {
- Message msg = new Message();
- msg.obj = new String(srv);
- error_handler.sendMessage(msg);
- } catch (Exception e) {
- }
- }
/*
* Handlers for thread functions that need to access GUI
@@ -498,25 +412,6 @@ public class FDroid extends TabActivity implements OnItemClickListener {
}
};
- private Handler error_handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (pd.isShowing())
- pd.dismiss();
- AlertDialog p = new AlertDialog.Builder(mctx).create();
- p.setTitle(getString(R.string.connection_timeout));
- p.setIcon(android.R.drawable.ic_dialog_alert);
- p.setMessage(getString(R.string.connection_error_msg) + ": < "
- + msg.obj.toString() + " >");
- p.setButton(getString(R.string.ok),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- return;
- }
- });
- p.show();
- }
- };
// Handler for a click on one of the items in an application list. Pops
// up a dialog that shows the details of the application and all its
diff --git a/src/org/fdroid/fdroid/Preferences.java b/src/org/fdroid/fdroid/Preferences.java
index cc24264cd..56dfebfaf 100644
--- a/src/org/fdroid/fdroid/Preferences.java
+++ b/src/org/fdroid/fdroid/Preferences.java
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2010 Ciaran Gultnieks, ciaran@ciarang.com
+ *
+ * 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 org.fdroid.fdroid;
import android.os.Bundle;
diff --git a/src/org/fdroid/fdroid/RepoXMLHandler.java b/src/org/fdroid/fdroid/RepoXMLHandler.java
index b89107b8d..3e6a8a6e3 100644
--- a/src/org/fdroid/fdroid/RepoXMLHandler.java
+++ b/src/org/fdroid/fdroid/RepoXMLHandler.java
@@ -23,18 +23,24 @@ import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.InputStreamReader;
import java.net.URL;
+import java.util.Vector;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
-import android.content.Context;
import android.util.Log;
public class RepoXMLHandler extends DefaultHandler {
- Context mctx;
String mserver;
private DB db;
@@ -43,8 +49,7 @@ public class RepoXMLHandler extends DefaultHandler {
private DB.Apk curapk = null;
private String curel = null;
- public RepoXMLHandler(Context ctx, String srv, DB db) {
- mctx = ctx;
+ public RepoXMLHandler(String srv, DB db) {
mserver = srv;
this.db = db;
}
@@ -173,4 +178,61 @@ public class RepoXMLHandler extends DefaultHandler {
}
}
+ private static String LOCAL_PATH = "/sdcard/.fdroid";
+ private static String XML_PATH = LOCAL_PATH + "/repotemp.xml";
+
+ public static void doUpdates(DB db) {
+ db.beginUpdate();
+ Vector repos = db.getRepos();
+ for (DB.Repo repo : repos) {
+ if (repo.inuse) {
+
+ try {
+
+ File f = new File(XML_PATH);
+ if (f.exists())
+ f.delete();
+
+ // Download the index file from the repo...
+ BufferedInputStream getit = new BufferedInputStream(
+ new URL(repo.address + "/index.xml").openStream());
+
+ FileOutputStream saveit = new FileOutputStream(XML_PATH);
+ BufferedOutputStream bout = new BufferedOutputStream(
+ saveit, 1024);
+ byte data[] = new byte[1024];
+
+ int readed = getit.read(data, 0, 1024);
+ while (readed != -1) {
+ bout.write(data, 0, readed);
+ readed = getit.read(data, 0, 1024);
+ }
+ bout.close();
+ getit.close();
+ saveit.close();
+
+ // Process the index...
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+ RepoXMLHandler handler = new RepoXMLHandler(repo.address, db);
+ xr.setContentHandler(handler);
+
+ InputStreamReader isr = new FileReader(new File(XML_PATH));
+ InputSource is = new InputSource(isr);
+ xr.parse(is);
+ File xml_file = new File(XML_PATH);
+ xml_file.delete();
+
+ } catch (Exception e) {
+ Log.d("FDroid", "Exception updating from " + repo.address
+ + " - " + e.getMessage());
+ }
+
+ }
+ }
+ db.endUpdate();
+
+ }
+
}
diff --git a/src/org/fdroid/fdroid/StartupReceiver.java b/src/org/fdroid/fdroid/StartupReceiver.java
new file mode 100644
index 000000000..19b44e295
--- /dev/null
+++ b/src/org/fdroid/fdroid/StartupReceiver.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 Ciaran Gultnieks, ciaran@ciarang.com
+ *
+ * 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 org.fdroid.fdroid;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class StartupReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context ctx, Intent intent) {
+ UpdateService.schedule(ctx);
+ }
+
+}
diff --git a/src/org/fdroid/fdroid/UpdateService.java b/src/org/fdroid/fdroid/UpdateService.java
new file mode 100644
index 000000000..91686db83
--- /dev/null
+++ b/src/org/fdroid/fdroid/UpdateService.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 Ciaran Gultnieks, ciaran@ciarang.com
+ *
+ * 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 org.fdroid.fdroid;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class UpdateService extends Service {
+
+ // Schedule (or cancel schedule for) this service, according to the
+ // current preferences. Should be called a) at boot, or b) if the preference
+ // is changed.
+ // TODO: What if we get upgraded?
+ public static void schedule(Context ctx) {
+
+ SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(ctx);
+ String sint = prefs.getString("updateInterval", "0");
+ int interval = Integer.parseInt(sint);
+
+ Intent intent = new Intent(ctx, UpdateService.class);
+ PendingIntent pending = PendingIntent.getService(ctx, 0, intent, 0);
+
+ AlarmManager alarm = (AlarmManager) ctx
+ .getSystemService(Context.ALARM_SERVICE);
+ alarm.cancel(pending);
+ if (interval > 0) {
+ alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
+ SystemClock.elapsedRealtime() + 5000,
+ AlarmManager.INTERVAL_HOUR, pending);
+ }
+
+ }
+
+ // For API levels <5
+ @Override
+ public void onStart(Intent intent, int startId) {
+ handleCommand();
+ }
+
+ // For API levels >=5
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ handleCommand();
+ return START_REDELIVER_INTENT;
+ }
+
+ private void handleCommand() {
+
+ new Thread() {
+ public void run() {
+
+ // See if it's time to actually do anything yet...
+ SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(getBaseContext());
+ 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;
+
+ // Make sure we have a connection...
+ ConnectivityManager netstate = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (netstate.getNetworkInfo(1).getState() != NetworkInfo.State.CONNECTED
+ && netstate.getNetworkInfo(0).getState() != NetworkInfo.State.CONNECTED)
+ return;
+
+ // Do the update...
+ DB db = null;
+ try {
+ db = new DB(getBaseContext());
+ RepoXMLHandler.doUpdates(db);
+ } catch(Exception e) {
+ Log.d("FDroid","Exception during handleCommand() - " + e.getMessage());
+ } finally {
+ if (db != null)
+ db.close();
+ stopSelf();
+ }
+
+ }
+ }.start();
+
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+}