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"); | ||||||
|          |          | ||||||
|         new Thread() { |         SharedPreferences prefs = PreferenceManager | ||||||
|             public void run() { |                 .getDefaultSharedPreferences(getBaseContext()); | ||||||
| 
 | 
 | ||||||
|                 // If we're in one of our list activities, we don't want |         // See if it's time to actually do anything yet... | ||||||
|                 // to run an update because the database will be out of |         if(receiver == null) { | ||||||
|                 // sync with the display. |             long lastUpdate = prefs.getLong("lastUpdateCheck", 0); | ||||||
|                 if (((FDroidApp) getApplication()).inActivity != 0) |             String sint = prefs.getString("updateInterval", "0"); | ||||||
|                     return; |             int interval = Integer.parseInt(sint); | ||||||
|  |             if (interval == 0) | ||||||
|  |                 return; | ||||||
|  |             if (lastUpdate + (interval * 60 * 60) > System | ||||||
|  |                     .currentTimeMillis()) | ||||||
|  |                 return; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|                 // See if it's time to actually do anything yet... |         // Do the update... | ||||||
|                 SharedPreferences prefs = PreferenceManager |         DB db = null; | ||||||
|                         .getDefaultSharedPreferences(getBaseContext()); |         try { | ||||||
|                 long lastUpdate = prefs.getLong("lastUpdateCheck", 0); |             db = new DB(getBaseContext()); | ||||||
|                 String sint = prefs.getString("updateInterval", "0"); |             boolean notify = prefs.getBoolean("updateNotify", false); | ||||||
|                 int interval = Integer.parseInt(sint); |  | ||||||
|                 if (interval == 0) |  | ||||||
|                     return; |  | ||||||
|                 if (lastUpdate + (interval * 60 * 60) > System |  | ||||||
|                         .currentTimeMillis()) |  | ||||||
|                     return; |  | ||||||
| 
 | 
 | ||||||
|                 // Do the update... |             // Get the number of updates available before we | ||||||
|                 DB db = null; |             // start, so we can notify if there are new ones. | ||||||
|                 try { |             // (But avoid doing it if the user doesn't want | ||||||
|                     db = new DB(getBaseContext()); |             // notifications, since it may be time consuming) | ||||||
|                     boolean notify = prefs.getBoolean("updateNotify", false); |             int prevUpdates = 0; | ||||||
|  |             if (notify) | ||||||
|  |                 prevUpdates = db.getNumUpdates(); | ||||||
| 
 | 
 | ||||||
|                     // Get the number of updates available before we |             boolean success = RepoXMLHandler.doUpdates( | ||||||
|                     // start, so we can notify if there are new ones. |                     getBaseContext(), db); | ||||||
|                     // (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( |             if (success && notify) { | ||||||
|                             getBaseContext(), db); |                 int newUpdates = db.getNumUpdates(); | ||||||
| 
 |                 Log.d("FDroid", "Updates before:" + prevUpdates + ", after: " +newUpdates);                         | ||||||
|                     if (success && notify) { |                 if (newUpdates > prevUpdates) { | ||||||
|                         int newUpdates = db.getNumUpdates(); |                     NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); | ||||||
|                         Log.d("FDroid", "Updates before:" + prevUpdates + ", after: " +newUpdates);                         |                     Notification notification = new Notification( | ||||||
|                         if (newUpdates > prevUpdates) { |                             R.drawable.icon, | ||||||
|                             NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |                             "FDroid Updates Available", System | ||||||
|                             Notification notification = new Notification( |                                     .currentTimeMillis()); | ||||||
|                                     R.drawable.icon, |                     Context context = getApplicationContext(); | ||||||
|                                     "FDroid Updates Available", System |                     CharSequence contentTitle = "FDroid"; | ||||||
|                                             .currentTimeMillis()); |                     CharSequence contentText = "Updates are available."; | ||||||
|                             Context context = getApplicationContext(); |                     Intent notificationIntent = new Intent( | ||||||
|                             CharSequence contentTitle = "FDroid"; |                             UpdateService.this, FDroid.class); | ||||||
|                             CharSequence contentText = "Updates are available."; |                     PendingIntent contentIntent = PendingIntent | ||||||
|                             Intent notificationIntent = new Intent( |                             .getActivity(UpdateService.this, 0, | ||||||
|                                     UpdateService.this, FDroid.class); |                                     notificationIntent, 0); | ||||||
|                             PendingIntent contentIntent = PendingIntent |                     notification.setLatestEventInfo(context, | ||||||
|                                     .getActivity(UpdateService.this, 0, |                             contentTitle, contentText, contentIntent); | ||||||
|                                             notificationIntent, 0); |                     notification.flags |= Notification.FLAG_AUTO_CANCEL; | ||||||
|                             notification.setLatestEventInfo(context, |                     n.notify(1, notification); | ||||||
|                                     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
	 Ciaran Gultnieks
						Ciaran Gultnieks