Commits

Anonymous committed 1c803c5 Draft

Add news checker service

  • Participants
  • Parent commits a44194d

Comments (0)

Files changed (9)

File AndroidManifest.xml

         <receiver
             android:name=".service.UpdateReceiver"
             android:process=":remote" />
+        <receiver
+            android:name=".service.NewsReceiver"
+            android:process=":remote" />
     </application>
 
 </manifest>

File res/values/arrays.xml

         <item>@string/adv_remove_symlink</item>
         <item>@string/adv_skip_symlink</item>
     </string-array>
+    <string-array name="news_update_frequency">
+        <item>@string/one_hour</item>
+        <item>@string/three_hours</item>
+        <item>@string/six_hours</item>
+        <item>@string/one_day</item>
+        <item>@string/never</item>
+    </string-array>
+    <string-array name="news_update_frequency_seconds">
+        <item>3600</item>
+        <item>10800</item>
+        <item>21600</item>
+        <item>86400</item>
+        <item>-1</item>
+    </string-array>
 </resources>

File res/values/strings.xml

     <string name="ps_debug_mode">Debug Mode</string>
     <string name="pt_troubleshoot">Troubleshoot</string>
     <string name="ps_email_logcat">Email logcat</string>
+	<string name="pt_news_check">News check frequency</string>
 
     <!-- CHECKBOX -->
     <string name="cb_symlink">Symlink applets</string>
     <string name="sunday">Sunday</string>
     <string name="adv_applet_title">Applet:</string>
     <string name="adv_current_symlink">Current symlink:</string>
+    <string name="one_hour">1 hour</string>
+    <string name="three_hours">3 hours</string>
+    <string name="six_hours">6 hours</string>
+    <string name="one_day">1 day</string>
+    <string name="never">Never</string>
 
 </resources>

File res/xml/busybox_prefs.xml

             android:key="check_at_boot_for_new_versions"
             android:summary="@string/ps_check_at_boot_for_new_versions"
             android:title="@string/pt_check_at_boot_for_new_versions" />
+
+        <ListPreference
+            android:defaultValue="3600"
+            android:dialogTitle="@string/pt_news_check"
+            android:entries="@array/news_update_frequency"
+            android:entryValues="@array/news_update_frequency_seconds"
+            android:key="news_check_frequency"
+            android:positiveButtonText="@string/db_cancel"
+            android:title="@string/pt_news_check" />
     </PreferenceCategory>
     <PreferenceCategory android:title="@string/pt_advanced" >
         <PreferenceScreen

File src/com/jrummy/busybox/installer/BusyboxActivity.java

 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.app.PendingIntent;
 import android.app.ProgressDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.widget.ListView;
 import android.widget.TextView;
 
+import com.jrummy.busybox.installer.service.NewsReceiver;
 import com.jrummy.busybox.installer.swipeytabs.SwipeyTabs;
 import com.jrummy.busybox.installer.swipeytabs.SwipeyTabsAdapter;
 import com.jrummy.busybox.installer.util.CMDProcessor;
 import com.jrummy.busybox.installer.util.Constants;
 import com.jrummy.busybox.installer.util.Helpers;
+import com.jrummy.busybox.installer.util.MainUtil;
 
 public class BusyboxActivity extends FragmentActivity {
 
 		mViewPager.setOffscreenPageLimit(2);
 		mViewPager.setCurrentItem(INSTALLER_TAB_POS);
 
+		SharedPreferences.Editor editor = mPrefs.edit();
+		int numOfUses = mPrefs.getInt("num_of_uses", 0);
+		editor.putInt("num_of_uses", numOfUses + 1);
+		if (!mPrefs.getBoolean("news_checker_enabled", false)) {
+			startNewsUpdateService();
+			editor.putBoolean("news_checker_enabled", true);
+		}
+		editor.commit();
+
 		mLoadApp.start();
 	}
 
 		}
 	}
 
+	private void startNewsUpdateService() {
+		int intervalInSeconds = Integer.parseInt(mPrefs.getString(
+				"news_check_frequency", "10"));
+		if (intervalInSeconds != -1) {
+			Intent it = new Intent(getApplicationContext(), NewsReceiver.class);
+			PendingIntent pi = MainUtil.getPendingIntent(getApplicationContext(), it);
+			Calendar calendar = Calendar.getInstance();
+			calendar.add(Calendar.SECOND, intervalInSeconds);
+			int interval = intervalInSeconds * 1000;
+			MainUtil.setRepeatingAlarm(getApplicationContext(), pi, calendar, interval);
+		}
+	}
+
 	@Override
 	protected Dialog onCreateDialog(final int id) {
 		if (id == DIALOG_WELCOME) {

File src/com/jrummy/busybox/installer/service/BootReceiver.java

 
 package com.jrummy.busybox.installer.service;
 
+import java.util.Calendar;
+
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import com.jrummy.busybox.installer.util.MainUtil;
 
 public class BootReceiver extends BroadcastReceiver {
 	@Override
 	public void onReceive(final Context context, final Intent intent) {
+		SharedPreferences preferences = PreferenceManager
+				.getDefaultSharedPreferences(context);
+		int intervalInSeconds = Integer.parseInt(preferences.getString(
+				"news_check_frequency", "3600"));
+		if (intervalInSeconds != -1) {
+			Intent it = new Intent(context, NewsReceiver.class);
+			PendingIntent pi = MainUtil.getPendingIntent(context, it);
+			Calendar calendar = Calendar.getInstance();
+			calendar.add(Calendar.SECOND, intervalInSeconds);
+			int interval = intervalInSeconds * 1000;
+			MainUtil.setRepeatingAlarm(context, pi, calendar, interval);
+		}
 		Intent i = new Intent(context, BootService.class);
 		context.startService(i);
 	}

File src/com/jrummy/busybox/installer/service/NewsReceiver.java

+package com.jrummy.busybox.installer.service;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Build;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.jrummy.busybox.installer.R;
+import com.jrummy.busybox.installer.util.MainUtil;
+
+public class NewsReceiver extends BroadcastReceiver {
+
+	private static final String TAG = "NewsReceiver";
+	private SharedPreferences mPrefs;
+
+	private static final String BASE_URL = "http://jrummy16.com/jrummy/news/";
+
+	@Override
+	public void onReceive(Context context, Intent intent) {
+		Log.i(TAG, "onReceive()");
+
+		mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+		String url = BASE_URL + context.getPackageName() + ".js";
+
+		if (MainUtil.IsConnectedToNetwork(context)) {
+			String json = MainUtil.readFromUrl(url);
+			try {
+				JSONObject jo = new JSONObject(json);
+
+				int id = jo.getInt("id");
+				boolean repeating = jo.getBoolean("repeating");
+				int minNumOfUses = jo.getInt("num_of_uses_min");
+				String device = jo.getString("device");
+				String type = jo.getString("type");
+				String dependency = jo.getString("dependency");
+				String promotedPackage = jo.getString("promoted_package");
+				String tickerText = jo.getString("ticker_text");
+				String contentTitle = jo.getString("content_title");
+				String contentText = jo.getString("content_text");
+				String link = jo.getString("url");
+				String packageName = jo.getString("package_name");
+				String componentName = jo.getString("component_name");
+
+				// Check if this device should get this message
+				if (!device.equals(Build.DEVICE) && !device.equals("all")) {
+					return;
+				} else if (mPrefs.getInt("num_of_uses", 0) < minNumOfUses) {
+					return;
+				}
+
+				if (!dependency.equals("") && !dependency.equals("none")) {
+					if (!MainUtil.isPackageInstalled(context, dependency)) {
+						return;
+					}
+				}
+
+				if (!promotedPackage.equals("") && !promotedPackage.equals("none")) {
+					if (MainUtil.isPackageInstalled(context, promotedPackage)) {
+						return;
+					}
+				}
+
+				if (mPrefs.getInt("news_id", -1) != id || repeating) {
+					SharedPreferences.Editor editor = mPrefs.edit();
+					editor.putInt("news_id", id);
+					editor.commit();
+
+					Intent it = null;
+
+					if (type.equals("app")) {
+						it = new Intent(Intent.ACTION_MAIN);
+						ComponentName component = new ComponentName(
+								packageName, componentName);
+						it.setComponent(component);
+						it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+					} else if (type.equals("url")) {
+						it = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
+					}
+
+					if (it != null) {
+						Notification nc = new Notification(R.drawable.titlebar_icon, 
+								tickerText, System.currentTimeMillis());
+						PendingIntent pi = PendingIntent.getActivity(context, 0, it, 0);
+						nc.defaults = Notification.DEFAULT_VIBRATE;
+						nc.flags |= Notification.FLAG_AUTO_CANCEL;
+						nc.setLatestEventInfo(context, contentTitle, contentText, pi);
+						((NotificationManager) context.getSystemService(
+								Context.NOTIFICATION_SERVICE)).notify(id, nc);
+					}
+				}
+
+			} catch (JSONException e) {
+				Log.e(TAG, "Failed parsing news. " + url, e);
+			}
+		}
+
+	}
+
+}
+

File src/com/jrummy/busybox/installer/util/Constants.java

+/*
+ * Copyright (C) 2012 Jared Rummler
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.jrummy.busybox.installer.util;
+
+
+public class Constants {
+	public static boolean IS_DEBUG = false;
+	public static final String CHMOD = "/data/data/com.jrummy.busybox.installer/files/chmod";
+}

File src/com/jrummy/busybox/installer/util/MainUtil.java

+package com.jrummy.busybox.installer.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Calendar;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.util.Log;
+import android.widget.Toast;
+
+public class MainUtil {
+
+	private static final String TAG = "MainUtil";
+
+	/**
+	 * Checks if a package is installed
+	 * 
+	 * @param context
+	 * @param packageName
+	 * 			Package name of the app
+	 * @return
+	 */
+	public static boolean isPackageInstalled(Context context, String packageName) {
+		try {
+			if (context.getPackageManager().getPackageInfo(packageName, 0) == null) {
+				return false;
+			}
+		} catch (NameNotFoundException nfe) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Checks if the SD card is mounted
+	 * 
+	 * @return
+	 */
+	public static boolean isSdPresent() {
+		return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
+	}
+
+	/**
+	 * Long toast message
+	 * 
+	 * @param c Application Context
+	 * @param msg Message to send
+	 */
+	public static void msgLong(final Context c, final String msg) {
+		if (c != null && msg != null) {
+			Toast.makeText(c, msg.trim(), Toast.LENGTH_LONG).show();
+		}
+	}
+
+	/**
+	 * Short toast message
+	 * 
+	 * @param c Application Context
+	 * @param msg Message to send
+	 */
+	public static void msgShort(final Context c, final String msg) {
+		if (c != null && msg != null) {
+			Toast.makeText(c, msg.trim(), Toast.LENGTH_SHORT).show();
+		}
+	}
+
+	/**
+	 * Long toast message
+	 * 
+	 * @param c Application Context
+	 * @param msg Message to send
+	 */
+	public static void sendMsg(final Context c, final String msg) {
+		if (c != null && msg != null) {
+			msgLong(c, msg);
+		}
+	}
+
+	public static boolean IsConnectedToNetwork(final Context context) {
+		final NetworkInfo[] allNetworkInfo = ((ConnectivityManager) context
+				.getSystemService(Context.CONNECTIVITY_SERVICE))
+				.getAllNetworkInfo();
+		NetworkInfo currNetworkInfo;
+		boolean anythingConnected = false;
+		for (final NetworkInfo element : allNetworkInfo) {
+			currNetworkInfo = element;
+			if (currNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
+				anythingConnected = true;
+			}
+		}
+		return anythingConnected;
+	}
+
+	public static void cancelAlarm(Context context, PendingIntent pi) {
+		AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+		am.cancel(pi);
+	}
+
+	public static PendingIntent getPendingIntent(Context context, Intent intent) {
+		PendingIntent pendingIntent = PendingIntent.getBroadcast(
+				context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+		return pendingIntent;
+	}
+
+	public static void setRepeatingAlarm(Context context, PendingIntent pi, 
+			Calendar calendar, long interval) {
+		AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+		am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), interval, pi);
+	}
+
+	public static String readFromUrl(String url) {
+		StringBuilder manifest = new StringBuilder();
+		InputStream is;
+		try {
+			is = new URL(url).openStream();
+			BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
+			int cp;
+			while ((cp = rd.read()) != -1) {
+				manifest.append((char) cp);
+			}
+			is.close();
+		} catch (MalformedURLException e1) {
+			Log.d(TAG, "Failed reading url " + url, e1);
+		} catch (IOException e1) {
+			Log.d(TAG, "Failed reading url " + url, e1);
+		}
+		return manifest.toString();
+	}
+
+
+
+}