diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6cbe4a78..bd649760 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -185,7 +185,15 @@
-
+
+
+
diff --git a/res/layout/activity_notification_filter.xml b/res/layout/activity_notification_filter.xml
new file mode 100644
index 00000000..66442b08
--- /dev/null
+++ b/res/layout/activity_notification_filter.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8d154b35..be25f6a1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -102,6 +102,8 @@
Add devices by IP
Noisy notifications
Vibrate and play a sound when receiving a file
+ Notification filter
+ Notifications will be synchronized for selected applications
Internal storage
All files
SD card %d
@@ -120,7 +122,6 @@
- 1 minute
- 2 minutes
-
- 10000000
- 20000000
diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java
new file mode 100644
index 00000000..2dbc249d
--- /dev/null
+++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2015 Vineet Garg
+ *
+ * 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 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * 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 .
+*/
+
+package org.kde.kdeconnect.Plugins.NotificationsPlugin;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+public class AppDatabase {
+
+ public static final String KEY_ROW_ID = "id";
+ public static final String KEY_NAME = "app";
+ public static final String KEY_PACKAGE_NAME = "packageName";
+ public static final String KEY_IS_FILTERED = "isFiltered";
+
+
+ private static final String DATABASE_NAME = "Applications";
+ private static final String DATABASE_TABLE = "Applications";
+ private static final int DATABASE_VESRION = 1;
+
+ private Context ourContext;
+ private SQLiteDatabase ourDatabase;
+ private DbHelper ourHelper;
+
+ public AppDatabase(Context c) {
+ ourContext = c;
+ }
+
+ private static class DbHelper extends SQLiteOpenHelper{
+
+ public DbHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VESRION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + DATABASE_TABLE + "(" + KEY_ROW_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + KEY_NAME + " TEXT NOT NULL, " + KEY_PACKAGE_NAME + " TEXT NOT NULL, " + KEY_IS_FILTERED + " TEXT NOT NULL); ");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int i, int i2) {
+ db.execSQL("DROP TABLE IF EXISTS "+ DATABASE_TABLE);
+ onCreate(db);
+
+ }
+
+ }
+
+ public AppDatabase open(){
+ ourHelper = new DbHelper(ourContext);
+ ourDatabase = ourHelper.getWritableDatabase();
+ return this;
+ }
+
+
+ public void close(){
+ ourHelper.close();
+ }
+
+ public Cursor getAllApplications()
+ {
+ String[] columns = new String []{KEY_ROW_ID,KEY_NAME,KEY_PACKAGE_NAME,KEY_IS_FILTERED} ;
+ Cursor res = ourDatabase.query(DATABASE_TABLE,columns,null,null,null,null,KEY_NAME);
+ return res;
+ }
+
+
+ public long createEntry(String app, String packagename,String isFiltered) {
+ ContentValues cv = new ContentValues();
+ cv.put(KEY_NAME,app);
+ cv.put(KEY_PACKAGE_NAME,packagename);
+ cv.put(KEY_IS_FILTERED,isFiltered);
+ return ourDatabase.insert(DATABASE_TABLE,null,cv);
+ }
+
+ public long updateEntry(String packageName, String value) {
+ ContentValues cvUpdate = new ContentValues();
+ cvUpdate.put(KEY_IS_FILTERED,value);
+ return ourDatabase.update(DATABASE_TABLE,cvUpdate,KEY_PACKAGE_NAME + "=?",new String[]{packageName});
+ }
+
+ public boolean checkEntry(String packageName) {
+ String[] columns = new String []{KEY_ROW_ID,KEY_NAME,KEY_PACKAGE_NAME,KEY_IS_FILTERED} ;
+ Cursor res = ourDatabase.query(DATABASE_TABLE,columns,KEY_PACKAGE_NAME + " =? ",new String[]{packageName},null,null,null);
+ if (res.getCount() != 0){
+ return true;
+ }else {
+ return false;
+ }
+
+ }
+
+ public boolean isFilterEnabled(String packageName){
+ String[] columns = new String []{KEY_ROW_ID,KEY_NAME,KEY_PACKAGE_NAME,KEY_IS_FILTERED} ;
+ Cursor res = ourDatabase.query(DATABASE_TABLE,columns,KEY_PACKAGE_NAME + " =? ",new String[]{packageName},null,null,null);
+ if (res.getCount() > 0){
+ res.moveToFirst();
+ if ((res.getString(res.getColumnIndex(KEY_IS_FILTERED))).equals("true")){
+ return true;
+ }else{
+ return false;
+ }
+ }else{
+ return true;
+ }
+ }
+ public void delete(String packageName){
+ ourDatabase.delete(DATABASE_TABLE,KEY_PACKAGE_NAME + " =? ",new String[]{packageName} );
+ }
+
+
+}
diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationFilterActivity.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationFilterActivity.java
new file mode 100644
index 00000000..0beff93b
--- /dev/null
+++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationFilterActivity.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2015 Vineet Garg
+ *
+ * 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 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * 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 .
+*/
+
+package org.kde.kdeconnect.Plugins.NotificationsPlugin;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import org.kde.kdeconnect_tp.R;
+
+import java.util.List;
+
+public class NotificationFilterActivity extends ActionBarActivity {
+
+ ListView listView;
+ AppDatabase appDatabase;
+ String[] appName;
+ String[][] database;
+ int i=0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_notification_filter);
+ listView = (ListView)findViewById(R.id.lvFilterApps);
+ appDatabase = new AppDatabase(this);
+
+ deleteUninstalledApps();
+ addNewlyInstalledApps();
+
+ appDatabase.open();
+ Cursor res = appDatabase.getAllApplications();
+ res.moveToFirst();
+
+ appName = new String[res.getCount()];
+ database = new String [res.getCount()][3];
+
+ while(!res.isAfterLast()){
+ appName[i] = res.getString(res.getColumnIndex(AppDatabase.KEY_NAME));
+ database[i][0] = res.getString(res.getColumnIndex(AppDatabase.KEY_NAME));
+ database[i][1] = res.getString(res.getColumnIndex(AppDatabase.KEY_PACKAGE_NAME));
+ database[i][2] = res.getString(res.getColumnIndex(AppDatabase.KEY_IS_FILTERED));
+
+ res.moveToNext();
+ i++;
+ }
+ appDatabase.close();
+
+
+ ArrayAdapter adapter = new ArrayAdapter(this,
+ android.R.layout.simple_list_item_multiple_choice,android.R.id.text1, appName);
+ listView.setAdapter(adapter);
+ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+
+ for (i=0 ; i adapterView, View view, int i, long l) {
+ appDatabase.open();
+ if (listView.isItemChecked(i)){
+ database[i][2] = "true" ;
+ appDatabase.updateEntry(database[i][1],"true");
+ }else{
+ database[i][2] = "false";
+ appDatabase.updateEntry(database[i][1],"false");
+ }
+ appDatabase.close();
+ }
+ });
+ }
+
+ // Delete apps from database which are uninstalled
+ private void deleteUninstalledApps(){
+ Cursor res;
+ appDatabase.open();
+ res = appDatabase.getAllApplications();
+ if (res != null){
+ res.moveToFirst();
+ while(res.isAfterLast() == false){
+ String packageName = res.getString(res.getColumnIndex(AppDatabase.KEY_PACKAGE_NAME));
+ if (!isPackageInstalled(packageName)){
+ appDatabase.delete(packageName);
+ }
+ res.moveToNext();
+ }
+ }
+ appDatabase.close();
+
+ }
+
+ // Adding newly installed apps in database
+ private void addNewlyInstalledApps(){
+
+ List PackList = getPackageManager().getInstalledApplications(0);
+ appDatabase.open();
+
+ for (int i=0; i < PackList.size(); i++)
+ {
+ ApplicationInfo PackInfo = PackList.get(i);
+
+ if ( (PackInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0 )
+ {
+ String AppName = PackInfo.loadLabel(getPackageManager()).toString();
+ String packageName = PackInfo.packageName;
+ if (!appDatabase.checkEntry(packageName)){
+ appDatabase.createEntry(PackInfo.loadLabel(getPackageManager()).toString(),
+ PackInfo.packageName,
+ "true");
+ }
+// Log.e("App : " + Integer.toString(i), AppName);
+ }else if ((PackInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0){
+ //ignore these apps
+ }else{
+ String packageName = PackInfo.packageName;
+ if (!appDatabase.checkEntry(packageName)){
+ appDatabase.createEntry(PackInfo.loadLabel(getPackageManager()).toString(),
+ PackInfo.packageName,
+ "true");
+ }
+ //Log.e("App : " + Integer.toString(i), AppName);
+ }
+ }
+
+ appDatabase.close();
+
+ }
+
+ private boolean isPackageInstalled(String packageName){
+ PackageManager pm = getPackageManager();
+ try{
+ pm.getPackageInfo(packageName,PackageManager.GET_META_DATA);
+ }catch (Exception e){
+ return false;
+ }
+ return true;
+ }
+
+
+
+
+}
diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
index f54c48f5..ab6383fd 100644
--- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
+++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
@@ -64,7 +64,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
@Override
public boolean hasSettings() {
- return false;
+ return true;
}
@Override
@@ -199,6 +199,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
public void sendNotification(StatusBarNotification statusBarNotification, boolean requestAnswer) {
Notification notification = statusBarNotification.getNotification();
+ AppDatabase appDatabase = new AppDatabase(context);
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0
|| (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0
@@ -207,6 +208,13 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
return;
}
+ appDatabase.open();
+ if (!appDatabase.isFilterEnabled(statusBarNotification.getPackageName())){
+ return;
+ // we dont want notification from this app
+ }
+ appDatabase.close();
+
NotificationId id = NotificationId.fromNotification(statusBarNotification);
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_NOTIFICATION);
diff --git a/src/org/kde/kdeconnect/UserInterface/PluginSettingsActivity.java b/src/org/kde/kdeconnect/UserInterface/PluginSettingsActivity.java
index abe1db15..240c16c6 100644
--- a/src/org/kde/kdeconnect/UserInterface/PluginSettingsActivity.java
+++ b/src/org/kde/kdeconnect/UserInterface/PluginSettingsActivity.java
@@ -23,6 +23,9 @@ package org.kde.kdeconnect.UserInterface;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
+import android.util.Log;
+
+import org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationFilterActivity;
public class PluginSettingsActivity extends PreferenceActivity {
@@ -31,7 +34,13 @@ public class PluginSettingsActivity extends PreferenceActivity {
super.onCreate(savedInstanceState);
String resource_name = getIntent().getStringExtra(Intent.EXTRA_INTENT);
- int resource_file = getResources().getIdentifier(resource_name, "xml", getPackageName());
- addPreferencesFromResource(resource_file);
+ if (resource_name.equals("plugin_notifications_preferences")){
+ Intent intent = new Intent(PluginSettingsActivity.this,NotificationFilterActivity.class);
+ startActivity(intent);
+ finish();
+ }else {
+ int resource_file = getResources().getIdentifier(resource_name, "xml", getPackageName());
+ addPreferencesFromResource(resource_file);
+ }
}
}