From a397114179d0b372f590b0e2b3a21fac25bbb8f2 Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Tue, 28 Feb 2012 17:11:08 +0100 Subject: [PATCH] Update service that checks for new app and search module versions. --- android/AndroidManifest.xml | 4 +- android/res/values/strings.xml | 3 +- .../src/org/transdroid/gui/search/Search.java | 7 +- .../org/transdroid/gui/util/ActivityUtil.java | 7 +- .../org/transdroid/service/BootReceiver.java | 6 +- .../transdroid/service/UpdateReceiver.java | 31 ++++ .../org/transdroid/service/UpdateService.java | 174 ++++++++++++++++++ 7 files changed, 219 insertions(+), 13 deletions(-) create mode 100644 android/src/org/transdroid/service/UpdateReceiver.java create mode 100644 android/src/org/transdroid/service/UpdateService.java diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 7db6aace..8db98970 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -18,8 +18,8 @@ --> diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index c0931ab4..ced567cc 100644 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -115,7 +115,8 @@ Use as new search Search saved as RSS feed Saving not supported for this site -Torrent Search is now a separate module, which means a one-time install from the Android Market. Install it now? +Torrent Search is a separate module, to be installed from the website. Download and install it now? +Download and install Transdroid preferences Add new server diff --git a/android/src/org/transdroid/gui/search/Search.java b/android/src/org/transdroid/gui/search/Search.java index 2157e4c8..0a07d046 100644 --- a/android/src/org/transdroid/gui/search/Search.java +++ b/android/src/org/transdroid/gui/search/Search.java @@ -79,7 +79,7 @@ import android.widget.Toast; public class Search extends FragmentActivity implements OnTouchListener, OnSelectedChangedListener { private static final String LOG_NAME = "Search"; - private final static Uri TTS_MARKET_URI = Uri.parse("market://search?q=pname:org.transdroid.search"); + private final static Uri TTS_MARKET_URI = Uri.parse("http://www.transdroid.org/latest-search"); private static final int MENU_REFRESH_ID = 1; private static final int MENU_SEARCH_ID = 2; @@ -462,8 +462,9 @@ public class Search extends FragmentActivity implements OnTouchListener, OnSelec case DIALOG_INSTALLSEARCH: - return ActivityUtil.buildInstallDialog(this, R.string.tts_not_found, TTS_MARKET_URI, true); - + return ActivityUtil.buildInstallDialog(this, R.string.tts_not_found, TTS_MARKET_URI, true, + getString(R.string.tts_install)); + } return super.onCreateDialog(id); diff --git a/android/src/org/transdroid/gui/util/ActivityUtil.java b/android/src/org/transdroid/gui/util/ActivityUtil.java index ca30890e..4de9e2df 100644 --- a/android/src/org/transdroid/gui/util/ActivityUtil.java +++ b/android/src/org/transdroid/gui/util/ActivityUtil.java @@ -58,22 +58,23 @@ public class ActivityUtil { * @return The dialog to show */ public static Dialog buildInstallDialog(final Activity activity, int messageResourceID, final Uri marketUri) { - return buildInstallDialog(activity, messageResourceID, marketUri, false); + return buildInstallDialog(activity, messageResourceID, marketUri, false, activity.getString(R.string.oifm_install)); } /** * Builds a (reusable) dialog that asks to install some application from the Android market * @param messageResourceID The message to show to the user * @param marketUri The application's URI on the Android Market + * @param buttonText The text to show on the positive (install) button * @param alternativeNegativeButtonHandler The click handler for the negative dialog button * @return The dialog to show */ public static Dialog buildInstallDialog(final Activity activity, int messageResourceID, final Uri marketUri, - final boolean closeAfterInstallFailure) { + final boolean closeAfterInstallFailure, CharSequence buttonText) { AlertDialog.Builder fbuilder = new AlertDialog.Builder(activity); fbuilder.setMessage(messageResourceID); fbuilder.setCancelable(true); - fbuilder.setPositiveButton(R.string.oifm_install, new DialogInterface.OnClickListener() { + fbuilder.setPositiveButton(buttonText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent install = new Intent(Intent.ACTION_VIEW, marketUri); diff --git a/android/src/org/transdroid/service/BootReceiver.java b/android/src/org/transdroid/service/BootReceiver.java index 68ed4ee6..8256373b 100644 --- a/android/src/org/transdroid/service/BootReceiver.java +++ b/android/src/org/transdroid/service/BootReceiver.java @@ -75,12 +75,10 @@ public class BootReceiver extends BroadcastReceiver { // Set up PendingIntent for the alarm service if (mgr == null) mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - mgr.cancel(pui); - Intent i = new Intent(context, UpdateReceiver.class); - pui = PendingIntent.getBroadcast(context, 0, i, 0); + pui = PendingIntent.getBroadcast(context, 1, i, 0); // First intent after a small (2 second) delay and repeat every day - mgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 2000, + mgr.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 2000, AlarmManager.INTERVAL_DAY, pui); } diff --git a/android/src/org/transdroid/service/UpdateReceiver.java b/android/src/org/transdroid/service/UpdateReceiver.java new file mode 100644 index 00000000..f19d88f2 --- /dev/null +++ b/android/src/org/transdroid/service/UpdateReceiver.java @@ -0,0 +1,31 @@ +/* + * This file is part of Transdroid + * + * Transdroid 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 3 of the License, or + * (at your option) any later version. + * + * Transdroid 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 Transdroid. If not, see . + * + */ +package org.transdroid.service; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class UpdateReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + context.startService(new Intent(context, UpdateService.class)); + } + +} diff --git a/android/src/org/transdroid/service/UpdateService.java b/android/src/org/transdroid/service/UpdateService.java new file mode 100644 index 00000000..f52ad2f7 --- /dev/null +++ b/android/src/org/transdroid/service/UpdateService.java @@ -0,0 +1,174 @@ +/* + * This file is part of Transdroid + * + * Transdroid 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 3 of the License, or + * (at your option) any later version. + * + * Transdroid 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 Transdroid. If not, see . + * + */ +package org.transdroid.service; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.AbstractHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; +import org.transdroid.R; +import org.transdroid.daemon.util.HttpHelper; +import org.transdroid.preferences.Preferences; +import org.transdroid.util.TLog; + +import android.app.IntentService; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.net.ConnectivityManager; +import android.net.Uri; +import android.preference.PreferenceManager; + +/** + * A service that checks if a new version of the app or the search module is available. + * + * @author erickok + */ +public class UpdateService extends IntentService { + + private static final String LATEST_URL_APP = "http://www.transdroid.org/update/latest-app.php"; + private static final String LATEST_URL_SEARCH = "http://www.transdroid.org/update/latest-search.php"; + private static final String PACKAGE_APP = "org.transdroid"; + private static final String PACKAGE_SEARCH = "org.transdroid.search"; + private static final String DOWNLOAD_URL_APP = "http://www.transdroid.org/latest"; + private static final String DOWNLOAD_URL_SEARCH = "http://www.transdroid.org/latest-search"; + private static final String LOG_NAME = "Update service"; + private static NotificationManager notificationManager; + + public UpdateService() { + super(LOG_NAME); + } + + @Override + protected void onHandleIntent(Intent intent) { + + // Check if the user has background data disabled + ConnectivityManager conn = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + if (!conn.getBackgroundDataSetting()) { + TLog.d(LOG_NAME, + "Skip checking for new app versions, since background data is disabled on a system-wide level"); + return; + } + + DefaultHttpClient httpclient = new DefaultHttpClient(); + + try { + + // Retrieve what is the latest released app and search module versions + String[] app = retrieveLatestVersion(httpclient, LATEST_URL_APP); + String[] search = retrieveLatestVersion(httpclient, LATEST_URL_SEARCH); + int appVersion = Integer.parseInt(app[0].trim()); + int searchVersion = Integer.parseInt(search[0].trim()); + + // New version of the app? + try { + PackageInfo appPackage = getPackageManager().getPackageInfo(PACKAGE_APP, 0); + if (appPackage.versionCode < appVersion) { + // New version available! Notify the user. + newNotification(getString(R.string.update_app_newversion), + getString(R.string.update_app_newversion), getString(R.string.update_updateto, + app[1].trim()), DOWNLOAD_URL_APP, 0); + } + } catch (NameNotFoundException e) { + // Not installed... this can never happen since this Service is part of the app itself. + } + + // New version of the search module? + try { + PackageInfo searchPackage = getPackageManager().getPackageInfo(PACKAGE_SEARCH, 0); + if (searchPackage.versionCode < searchVersion) { + // New version available! Notify the user. + newNotification(getString(R.string.update_search_newversion), + getString(R.string.update_search_newversion), getString(R.string.update_updateto, + search[1].trim()), DOWNLOAD_URL_SEARCH, 0); + } + } catch (NameNotFoundException e) { + // The search module isn't installed yet at all; ignore and wait for the user to manually + // install it (when the first search is initiated) + } + + } catch (Exception e) { + // Cannot check right now for some reason; log and `ignore + TLog.d(LOG_NAME, "Cannot retrieve latest app or search module version code from the site: " + e.toString()); + } + + } + + private String[] retrieveLatestVersion(AbstractHttpClient httpclient, String url) throws ClientProtocolException, IOException { + + // Retrieve what is the latest released app version + HttpResponse request = httpclient.execute(new HttpGet(url)); + InputStream stream = request.getEntity().getContent(); + String appVersion[] = HttpHelper.ConvertStreamToString(stream).split("\\|"); + stream.close(); + return appVersion; + + } + + private void newNotification(String ticker, String title, String text, String downloadUrl, int notifyID) { + + // Use the alarm service settings for the notification sound/vibrate/colour + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + AlarmSettings settings = Preferences.readAlarmSettings(prefs); + + // Set up an intent that will initiate a download of the new version + Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(downloadUrl)); + + // Create a new notification + Notification newNotification = new Notification(R.drawable.icon_notification, ticker, System + .currentTimeMillis()); + newNotification.flags = Notification.FLAG_AUTO_CANCEL; + newNotification.setLatestEventInfo(getApplicationContext(), title, text, PendingIntent.getActivity( + getApplicationContext(), notifyID, i, 0)); + + // Get the system notification manager, if not done so previously + if (notificationManager == null) { + notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + } + + // If sound enabled add to notification + if (settings.getAlarmPlaySound() && settings.getAlarmSoundURI() != null) { + newNotification.sound = Uri.parse(settings.getAlarmSoundURI()); + } + + // If vibration enabled add to notification + if (settings.getAlarmVibrate()) { + newNotification.defaults = Notification.DEFAULT_VIBRATE; + } + + // Add coloured light; defaults to 0xff7dbb21 + newNotification.ledARGB = settings.getAlarmColour(); + newNotification.ledOnMS = 600; + newNotification.ledOffMS = 1000; + newNotification.flags |= Notification.FLAG_SHOW_LIGHTS; + + // Send notification + notificationManager.notify(notifyID, newNotification); + + } + +}