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); | ||||
|         compatChecker = db.getCompatibilityChecker(); | ||||
|         mPm = getPackageManager(); | ||||
|         ((FDroidApp) getApplication()).inActivity++; | ||||
|         // Get the preferences we're going to use in this Activity... | ||||
|         SharedPreferences prefs = PreferenceManager | ||||
|                 .getDefaultSharedPreferences(getBaseContext()); | ||||
| @ -238,7 +237,6 @@ public class AppDetails extends ListActivity { | ||||
|     protected void onStop() { | ||||
|         db.close(); | ||||
|         db = null; | ||||
|         ((FDroidApp) getApplication()).inActivity--; | ||||
|         super.onStop(); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -31,6 +31,7 @@ import android.app.AlertDialog; | ||||
| import android.app.ProgressDialog; | ||||
| import android.app.TabActivity; | ||||
| import android.app.AlertDialog.Builder; | ||||
| import android.content.Context; | ||||
| import android.content.DialogInterface; | ||||
| import android.content.Intent; | ||||
| import android.content.pm.PackageInfo; | ||||
| @ -39,6 +40,7 @@ import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.os.Message; | ||||
| import android.os.ResultReceiver; | ||||
| import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.Menu; | ||||
| @ -135,7 +137,6 @@ public class FDroid extends TabActivity implements OnItemClickListener, | ||||
|     @Override | ||||
|     protected void onStart() { | ||||
|         super.onStart(); | ||||
|         ((FDroidApp) getApplication()).inActivity++; | ||||
|         db = new DB(this); | ||||
|         triedEmptyUpdate = false; | ||||
|         populateLists(true); | ||||
| @ -144,7 +145,6 @@ public class FDroid extends TabActivity implements OnItemClickListener, | ||||
|     @Override | ||||
|     protected void onStop() { | ||||
|         db.close(); | ||||
|         ((FDroidApp) getApplication()).inActivity--; | ||||
|         super.onStop(); | ||||
|     } | ||||
| 
 | ||||
| @ -415,26 +415,15 @@ public class FDroid extends TabActivity implements OnItemClickListener, | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private void updateRepos() { | ||||
|         pd = ProgressDialog.show(this, getString(R.string.process_wait_title), | ||||
|                 getString(R.string.process_update_msg), true); | ||||
|         pd.setIcon(android.R.drawable.ic_dialog_info); | ||||
| 
 | ||||
|         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() { | ||||
|     // For receiving results from the UpdateService when we've told it to | ||||
|     // update in response to a user request. | ||||
|     private class UpdateReceiver extends ResultReceiver { | ||||
|         public UpdateReceiver(Handler handler) { | ||||
|             super(handler); | ||||
|         } | ||||
|         @Override | ||||
|         public void handleMessage(Message msg) { | ||||
|             if (msg.what == 1) { | ||||
|         protected void onReceiveResult (int resultCode, Bundle resultData) { | ||||
|             if (resultCode == 1) { | ||||
|                 Toast.makeText(FDroid.this, | ||||
|                         getString(R.string.connection_error_msg), | ||||
|                         Toast.LENGTH_LONG).show(); | ||||
| @ -444,7 +433,22 @@ public class FDroid extends TabActivity implements OnItemClickListener, | ||||
|             if (pd.isShowing()) | ||||
|                 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, | ||||
|             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 | ||||
|  * modify it under the terms of the GNU General Public License | ||||
| @ -22,10 +22,5 @@ import android.app.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 | ||||
|  * modify it under the terms of the GNU General Public License | ||||
| @ -19,6 +19,7 @@ | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.app.AlarmManager; | ||||
| import android.app.IntentService; | ||||
| import android.app.Notification; | ||||
| import android.app.NotificationManager; | ||||
| import android.app.PendingIntent; | ||||
| @ -26,12 +27,19 @@ import android.app.Service; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Bundle; | ||||
| import android.os.IBinder; | ||||
| import android.os.ResultReceiver; | ||||
| import android.os.SystemClock; | ||||
| import android.preference.PreferenceManager; | ||||
| 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 | ||||
|     // 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, | ||||
|                     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; | ||||
|     } | ||||
|     protected void onHandleIntent(Intent 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() { | ||||
|             public void run() { | ||||
|         // See if it's time to actually do anything yet... | ||||
|         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 | ||||
|                 // to run an update because the database will be out of | ||||
|                 // sync with the display. | ||||
|                 if (((FDroidApp) getApplication()).inActivity != 0) | ||||
|                     return; | ||||
|         // Do the update... | ||||
|         DB db = null; | ||||
|         try { | ||||
|             db = new DB(getBaseContext()); | ||||
|             boolean notify = prefs.getBoolean("updateNotify", false); | ||||
| 
 | ||||
|                 // 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; | ||||
|             // Get the number of updates available before we | ||||
|             // start, so we can notify if there are new ones. | ||||
|             // (But avoid doing it if the user doesn't want | ||||
|             // notifications, since it may be time consuming) | ||||
|             int prevUpdates = 0; | ||||
|             if (notify) | ||||
|                 prevUpdates = db.getNumUpdates(); | ||||
| 
 | ||||
|                 // Do the update... | ||||
|                 DB db = null; | ||||
|                 try { | ||||
|                     db = new DB(getBaseContext()); | ||||
|                     boolean notify = prefs.getBoolean("updateNotify", false); | ||||
|             boolean success = RepoXMLHandler.doUpdates( | ||||
|                     getBaseContext(), db); | ||||
| 
 | ||||
|                     // Get the number of updates available before we | ||||
|                     // start, so we can notify if there are new ones. | ||||
|                     // (But avoid doing it if the user doesn't want | ||||
|                     // notifications, since it may be time consuming) | ||||
|                     int prevUpdates = 0; | ||||
|                     if (notify) | ||||
|                         prevUpdates = db.getNumUpdates(); | ||||
| 
 | ||||
|                     boolean success = RepoXMLHandler.doUpdates( | ||||
|                             getBaseContext(), db); | ||||
| 
 | ||||
|                     if (success && notify) { | ||||
|                         int newUpdates = db.getNumUpdates(); | ||||
|                         Log.d("FDroid", "Updates before:" + prevUpdates + ", after: " +newUpdates);                         | ||||
|                         if (newUpdates > prevUpdates) { | ||||
|                             NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); | ||||
|                             Notification notification = new Notification( | ||||
|                                     R.drawable.icon, | ||||
|                                     "FDroid Updates Available", System | ||||
|                                             .currentTimeMillis()); | ||||
|                             Context context = getApplicationContext(); | ||||
|                             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(); | ||||
|             if (success && notify) { | ||||
|                 int newUpdates = db.getNumUpdates(); | ||||
|                 Log.d("FDroid", "Updates before:" + prevUpdates + ", after: " +newUpdates);                         | ||||
|                 if (newUpdates > prevUpdates) { | ||||
|                     NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); | ||||
|                     Notification notification = new Notification( | ||||
|                             R.drawable.icon, | ||||
|                             "FDroid Updates Available", System | ||||
|                                     .currentTimeMillis()); | ||||
|                     Context context = getApplicationContext(); | ||||
|                     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); | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|         }.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
	 Ciaran Gultnieks
						Ciaran Gultnieks