First effort (untested) at doing scheduled repo updates
This commit is contained in:
parent
53a9e0e796
commit
9c193f237d
@ -15,9 +15,20 @@
|
||||
<activity android:name="Settings" />
|
||||
<activity android:name="AppDetails" />
|
||||
<activity android:name="Preferences" />
|
||||
|
||||
<receiver android:name="StartupReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<category android:name="android.intent.category.HOME" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name="UpdateService" />
|
||||
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
</manifest>
|
||||
|
@ -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.");
|
||||
|
@ -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<DB.Repo> 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
|
||||
|
@ -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;
|
||||
|
@ -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<DB.Repo> 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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
32
src/org/fdroid/fdroid/StartupReceiver.java
Normal file
32
src/org/fdroid/fdroid/StartupReceiver.java
Normal file
@ -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);
|
||||
}
|
||||
|
||||
}
|
120
src/org/fdroid/fdroid/UpdateService.java
Normal file
120
src/org/fdroid/fdroid/UpdateService.java
Normal file
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user