diff --git a/.gitignore b/.gitignore index d16cb3d..ed1c528 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,10 @@ proguard/ *.iml *.ipr *.iws -.idea/ \ No newline at end of file +.idea/ + +#export folder +export/ + +#key file +key.key \ No newline at end of file diff --git a/project.properties b/project.properties index ca965e5..3efc82e 100644 --- a/project.properties +++ b/project.properties @@ -12,4 +12,5 @@ # Project target. target=android-17 -android.library.reference.1=../locale-api +android.library.reference.1=../display/locale-api +android.library=false diff --git a/res/values/strings.xml b/res/values/strings.xml index 4e2783c..fa2762c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,6 +1,5 @@ - Pebble Notifier My pebble notification title Notification body goes here! You can use any tasker variables such as %NTITLE for the notification title @@ -84,5 +83,6 @@ Do you want to remove the rename for This can\'t be blank Case\nInsensitive + Don\'t repeat notification \ No newline at end of file diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 7a762d7..e5f323d 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -18,6 +18,9 @@ android:key="pref_no_ongoing_notif" android:summary="@string/pref_no_ongoing_notif_summ" android:title="@string/pref_no_ongoing_notif" /> + queue; + private Mode mode = Mode.EXCLUDE; + private boolean notifications_only = false; + private boolean no_ongoing_notifs = false; + private boolean notification_extras = false; + private boolean quiet_hours = false; + private boolean notifScreenOn = true; + private boolean dontThrowManyTime = false; + private JSONArray converts = new JSONArray(); + private JSONArray ignores = new JSONArray(); + private JSONArray pkg_renames = new JSONArray(); + private long min_notification_wait = 0 * 1000; + private long notification_last_sent = 0; + private Date quiet_hours_before = null; + private Date quiet_hours_after = null; + private String[] packages = null; + private Handler mHandler; + private File watchFile; + private Long lastChange; + private HashMap previousNotification = null; + Queue queue; @Override public void onAccessibilityEvent(AccessibilityEvent event) { @@ -92,25 +99,26 @@ public void onAccessibilityEvent(AccessibilityEvent event) { return; } - //handle quiet hours - if(quiet_hours){ + // handle quiet hours + if (quiet_hours) { Calendar c = Calendar.getInstance(); Date now = new Date(0, 0, 0, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE)); if (Constants.IS_LOGGABLE) { - Log.i(Constants.LOG_TAG, "Checking quiet hours. Now: " + now.toString() + " vs " + - quiet_hours_before.toString() + " and " +quiet_hours_after.toString()); + Log.i(Constants.LOG_TAG, + "Checking quiet hours. Now: " + now.toString() + " vs " + quiet_hours_before.toString() + + " and " + quiet_hours_after.toString()); } - if(quiet_hours_before.after(quiet_hours_after)){ - if(now.after(quiet_hours_after) && now.before(quiet_hours_before)){ + if (quiet_hours_before.after(quiet_hours_after)) { + if (now.after(quiet_hours_after) && now.before(quiet_hours_before)) { if (Constants.IS_LOGGABLE) { Log.i(Constants.LOG_TAG, "Time is during quiet time. Returning."); } return; } - } else if(now.before(quiet_hours_before) || now.after(quiet_hours_after)){ + } else if (now.before(quiet_hours_before) || now.after(quiet_hours_after)) { if (Constants.IS_LOGGABLE) { Log.i(Constants.LOG_TAG, "Time is before or after the quiet hours time. Returning."); } @@ -133,11 +141,11 @@ public void onAccessibilityEvent(AccessibilityEvent event) { } } } - if (no_ongoing_notifs){ + if (no_ongoing_notifs) { Parcelable parcelable = event.getParcelableData(); if (parcelable instanceof Notification) { Notification notif = (Notification) parcelable; - if ((notif.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT){ + if ((notif.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT) { if (Constants.IS_LOGGABLE) { Log.i(Constants.LOG_TAG, "Event is a notification, notification flag contains ongoing, and no ongoing notification is true. Returning."); @@ -146,13 +154,11 @@ public void onAccessibilityEvent(AccessibilityEvent event) { } } else { if (Constants.IS_LOGGABLE) { - Log.i(Constants.LOG_TAG, - "Event is not a notification."); + Log.i(Constants.LOG_TAG, "Event is not a notification."); } } } - // Handle the do not disturb screen on settings PowerManager powMan = (PowerManager) this.getSystemService(Context.POWER_SERVICE); if (Constants.IS_LOGGABLE) { @@ -177,7 +183,7 @@ public void onAccessibilityEvent(AccessibilityEvent event) { PackageManager pm = getPackageManager(); String eventPackageName; - if (event.getPackageName() != null){ + if (event.getPackageName() != null) { eventPackageName = event.getPackageName().toString(); } else { eventPackageName = ""; @@ -230,13 +236,13 @@ public void onAccessibilityEvent(AccessibilityEvent event) { String title = ""; try { boolean renamed = false; - for(int i = 0; i < pkg_renames.length(); i++){ - if(pkg_renames.getJSONObject(i).getString("pkg").equalsIgnoreCase(eventPackageName)){ + for (int i = 0; i < pkg_renames.length(); i++) { + if (pkg_renames.getJSONObject(i).getString("pkg").equalsIgnoreCase(eventPackageName)) { renamed = true; title = pkg_renames.getJSONObject(i).getString("to"); } } - if(!renamed){ + if (!renamed) { title = pm.getApplicationLabel(pm.getApplicationInfo(eventPackageName, 0)).toString(); } } catch (NameNotFoundException e) { @@ -266,48 +272,67 @@ public void onAccessibilityEvent(AccessibilityEvent event) { } // Check ignore lists - for(int i = 0; i < ignores.length(); i++){ - try{ + for (int i = 0; i < ignores.length(); i++) { + try { JSONObject ignore = ignores.getJSONObject(i); String app = ignore.getString("app"); boolean exclude = ignore.optBoolean("exclude", true); boolean case_insensitive = ignore.optBoolean("insensitive", true); - if((!app.equals("-1")) && (!eventPackageName.equalsIgnoreCase(app))){ - //this rule doesn't apply to all apps and this isn't the app we're looking for. + if ((!app.equals("-1")) && (!eventPackageName.equalsIgnoreCase(app))) { + // this rule doesn't apply to all apps and this isn't the + // app we're looking for. continue; } String regex = ""; - if(case_insensitive){ + if (case_insensitive) { regex += "(?i)"; } - if(!ignore.getBoolean("raw")){ + if (!ignore.getBoolean("raw")) { regex += Pattern.quote(ignore.getString("match")); } else { regex += ignore.getString("match"); } Pattern p = Pattern.compile(regex); Matcher m = p.matcher(notificationText); - if(m.find()){ - if(exclude){ + if (m.find()) { + if (exclude) { if (Constants.IS_LOGGABLE) { - Log.i(Constants.LOG_TAG, "Notification text of '" + notificationText + "' matches: '" + regex +"' and exclude is on. Returning"); + Log.i(Constants.LOG_TAG, "Notification text of '" + notificationText + "' matches: '" + + regex + "' and exclude is on. Returning"); } return; } } else { - if(!exclude){ - if(Constants.IS_LOGGABLE){ - Log.i(Constants.LOG_TAG, "Notification text of '" + notificationText + "' does not match: '" + regex +"' and include is on. Returning"); + if (!exclude) { + if (Constants.IS_LOGGABLE) { + Log.i(Constants.LOG_TAG, "Notification text of '" + notificationText + + "' does not match: '" + regex + "' and include is on. Returning"); } return; } } - } catch (JSONException e){ + } catch (JSONException e) { continue; } } + // validate don't throw same notification + try { + if (dontThrowManyTime) { + if (previousNotification == null) { + previousNotification = new HashMap(); + } + if (previousNotification.containsKey(eventPackageName) + && previousNotification.get(eventPackageName).equalsIgnoreCase(notificationText)) { + Log.i(Constants.LOG_TAG, "Notification many time =" + notificationText); + return; + } + } + previousNotification.put(eventPackageName, notificationText); + } catch (Exception e) { + e.printStackTrace(); + } // Send the alert to Pebble @@ -328,18 +353,19 @@ private void sendToPebble(String title, String notificationText) { } return; } - for(int i = 0; i < converts.length(); i++){ + for (int i = 0; i < converts.length(); i++) { String from; String to; - try{ + try { JSONObject convert = converts.getJSONObject(i); from = "(?i)" + Pattern.quote(convert.getString("from")); to = convert.getString("to"); - } catch (JSONException e){ + } catch (JSONException e) { continue; } - //not sure if the title should be replaced as well or not. I'm guessing not - //title = title.replaceAll(from, to); + // not sure if the title should be replaced as well or not. I'm + // guessing not + // title = title.replaceAll(from, to); notificationText = notificationText.replaceAll(from, to); } @@ -405,16 +431,22 @@ private void loadPrefs() { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPreferences = getSharedPreferences(Constants.LOG_TAG, MODE_MULTI_PROCESS | MODE_PRIVATE); - //if old preferences exist, convert them. - if(sharedPreferences.contains(Constants.LOG_TAG + ".mode")){ + // if old preferences exist, convert them. + if (sharedPreferences.contains(Constants.LOG_TAG + ".mode")) { SharedPreferences.Editor editor = sharedPref.edit(); - editor.putInt(Constants.PREFERENCE_MODE, sharedPreferences.getInt(Constants.LOG_TAG + ".mode", Constants.Mode.OFF.ordinal())); - editor.putString(Constants.PREFERENCE_PACKAGE_LIST, sharedPreferences.getString(Constants.LOG_TAG + ".packageList", "")); - editor.putBoolean(Constants.PREFERENCE_NOTIFICATIONS_ONLY, sharedPreferences.getBoolean(Constants.LOG_TAG + ".notificationsOnly", true)); - editor.putBoolean(Constants.PREFERENCE_NOTIFICATION_EXTRA, sharedPreferences.getBoolean(Constants.LOG_TAG + ".fetchNotificationExtras", false)); + editor.putInt(Constants.PREFERENCE_MODE, + sharedPreferences.getInt(Constants.LOG_TAG + ".mode", Constants.Mode.OFF.ordinal())); + editor.putString(Constants.PREFERENCE_PACKAGE_LIST, + sharedPreferences.getString(Constants.LOG_TAG + ".packageList", "")); + editor.putBoolean(Constants.PREFERENCE_NOTIFICATIONS_ONLY, + sharedPreferences.getBoolean(Constants.LOG_TAG + ".notificationsOnly", true)); + editor.putBoolean(Constants.PREFERENCE_NOTIFICATION_EXTRA, + sharedPreferences.getBoolean(Constants.LOG_TAG + ".fetchNotificationExtras", false)); + editor.putBoolean(Constants.PREFERENCE_DONT_THROW_MANY_TIME, + sharedPreferences.getBoolean(Constants.LOG_TAG + ".dontThrowManyTime", false)); editor.commit(); - //clear out all old preferences + // clear out all old preferences editor = sharedPreferences.edit(); editor.clear(); editor.commit(); @@ -438,25 +470,27 @@ private void loadPrefs() { notification_extras = sharedPref.getBoolean(Constants.PREFERENCE_NOTIFICATION_EXTRA, false); notifScreenOn = sharedPref.getBoolean(Constants.PREFERENCE_NOTIF_SCREEN_ON, true); quiet_hours = sharedPref.getBoolean(Constants.PREFERENCE_QUIET_HOURS, false); - try{ + dontThrowManyTime = sharedPref.getBoolean(Constants.PREFERENCE_DONT_THROW_MANY_TIME, false); + try { converts = new JSONArray(sharedPref.getString(Constants.PREFERENCE_CONVERTS, "[]")); - } catch (JSONException e){ + } catch (JSONException e) { converts = new JSONArray(); } - try{ + try { ignores = new JSONArray(sharedPref.getString(Constants.PREFERENCE_IGNORE, "[]")); - } catch (JSONException e){ + } catch (JSONException e) { ignores = new JSONArray(); } - try{ + try { pkg_renames = new JSONArray(sharedPref.getString(Constants.PREFERENCE_PKG_RENAMES, "[]")); - } catch (JSONException e){ + } catch (JSONException e) { pkg_renames = new JSONArray(); } - //we only need to pull this if quiet hours are enabled. Save the cycles for the cpu! (haha) - if(quiet_hours){ + // we only need to pull this if quiet hours are enabled. Save the cycles + // for the cpu! (haha) + if (quiet_hours) { String[] pieces = sharedPref.getString(Constants.PREFERENCE_QUIET_HOURS_BEFORE, "00:00").split(":"); - quiet_hours_before= new Date(0, 0, 0, Integer.parseInt(pieces[0]), Integer.parseInt(pieces[1])); + quiet_hours_before = new Date(0, 0, 0, Integer.parseInt(pieces[0]), Integer.parseInt(pieces[1])); pieces = sharedPref.getString(Constants.PREFERENCE_QUIET_HOURS_AFTER, "23:59").split(":"); quiet_hours_after = new Date(0, 0, 0, Integer.parseInt(pieces[0]), Integer.parseInt(pieces[1])); } diff --git a/src/com/dattasmoon/pebble/plugin/SettingsActivity.java b/src/com/dattasmoon/pebble/plugin/SettingsActivity.java index 17ff2f8..231a1f5 100644 --- a/src/com/dattasmoon/pebble/plugin/SettingsActivity.java +++ b/src/com/dattasmoon/pebble/plugin/SettingsActivity.java @@ -21,6 +21,9 @@ of this software and associated documentation files (the "Software"), to deal */ package com.dattasmoon.pebble.plugin; +import java.io.File; +import java.io.IOException; + import android.app.Dialog; import android.content.Intent; import android.content.SharedPreferences; @@ -35,9 +38,7 @@ of this software and associated documentation files (the "Software"), to deal import android.view.Window; import android.widget.Toast; -import java.io.File; -import java.io.IOException; - +import com.dattasmoon.pebble.plugin.R; /** * This activity handles any logic for the settings screen (of which there is\ * currently none.) @@ -55,17 +56,24 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SharedPreferences sharedPreferences = getSharedPreferences(Constants.LOG_TAG, MODE_MULTI_PROCESS | MODE_PRIVATE); - //if old preferences exist, convert them. - if(sharedPreferences.contains(Constants.LOG_TAG + ".mode")){ - SharedPreferences sharedPref = getSharedPreferences(Constants.LOG_TAG + "_preferences", MODE_MULTI_PROCESS | MODE_PRIVATE); + // if old preferences exist, convert them. + if (sharedPreferences.contains(Constants.LOG_TAG + ".mode")) { + SharedPreferences sharedPref = getSharedPreferences(Constants.LOG_TAG + "_preferences", MODE_MULTI_PROCESS + | MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); - editor.putInt(Constants.PREFERENCE_MODE, sharedPreferences.getInt(Constants.LOG_TAG + ".mode", Constants.Mode.OFF.ordinal())); - editor.putString(Constants.PREFERENCE_PACKAGE_LIST, sharedPreferences.getString(Constants.LOG_TAG + ".packageList", "")); - editor.putBoolean(Constants.PREFERENCE_NOTIFICATIONS_ONLY, sharedPreferences.getBoolean(Constants.LOG_TAG + ".notificationsOnly", true)); - editor.putBoolean(Constants.PREFERENCE_NOTIFICATION_EXTRA, sharedPreferences.getBoolean(Constants.LOG_TAG + ".fetchNotificationExtras", false)); + editor.putInt(Constants.PREFERENCE_MODE, + sharedPreferences.getInt(Constants.LOG_TAG + ".mode", Constants.Mode.OFF.ordinal())); + editor.putString(Constants.PREFERENCE_PACKAGE_LIST, + sharedPreferences.getString(Constants.LOG_TAG + ".packageList", "")); + editor.putBoolean(Constants.PREFERENCE_NOTIFICATIONS_ONLY, + sharedPreferences.getBoolean(Constants.LOG_TAG + ".notificationsOnly", true)); + editor.putBoolean(Constants.PREFERENCE_NOTIFICATION_EXTRA, + sharedPreferences.getBoolean(Constants.LOG_TAG + ".fetchNotificationExtras", false)); + editor.putBoolean(Constants.PREFERENCE_DONT_THROW_MANY_TIME, + sharedPreferences.getBoolean(Constants.LOG_TAG + ".dontThrowManyTime", false)); editor.commit(); - //clear out all old preferences + // clear out all old preferences editor = sharedPreferences.edit(); editor.clear(); editor.commit(); @@ -89,7 +97,7 @@ protected void onCreate(Bundle savedInstanceState) { @Override public boolean onPreferenceClick(Preference preference) { pref_version_clicks++; - if(pref_version_clicks > 5){ + if (pref_version_clicks > 5) { final Dialog easterDialog = new Dialog(SettingsActivity.this); easterDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); easterDialog.setContentView(getLayoutInflater().inflate(R.layout.dialog_easter_hidden, null)); @@ -104,14 +112,14 @@ public void onClick(View v) { } return true; - } }); Preference pref_donate = findPreference("pref_donate"); pref_donate.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override public boolean onPreferenceClick(Preference preference) { - //send intent + // send intent Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(Constants.DONATION_URL)); startActivity(i); @@ -119,11 +127,10 @@ public boolean onPreferenceClick(Preference preference) { } }); - } @Override - protected void onPause(){ + protected void onPause() { File watchFile = new File(getFilesDir() + "PrefsChanged.none"); if (!watchFile.exists()) { try {