diff --git a/res/layout/activity_notification_filter.xml b/res/layout/activity_notification_filter.xml
index 9c2f64d5..2c178011 100644
--- a/res/layout/activity_notification_filter.xml
+++ b/res/layout/activity_notification_filter.xml
@@ -15,10 +15,18 @@
android:paddingBottom="5dp"
android:id="@+id/tFilter"/>
+
+
diff --git a/src/org/kde/kdeconnect/Helpers/StringsHelper.java b/src/org/kde/kdeconnect/Helpers/StringsHelper.java
index 5e567855..2c00c9b2 100644
--- a/src/org/kde/kdeconnect/Helpers/StringsHelper.java
+++ b/src/org/kde/kdeconnect/Helpers/StringsHelper.java
@@ -6,4 +6,11 @@ public class StringsHelper {
public static final Charset UTF8 = Charset.forName("UTF-8");
+ public static int compare(String a, String b) {
+ if (a == b) return 0;
+ if (a == null) return -1;
+ if (b == null) return 1;
+ return a.compareToIgnoreCase(b);
+ }
+
}
diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java
index 45bc9ab9..404199c8 100644
--- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java
+++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java
@@ -26,26 +26,32 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
+import java.util.HashSet;
+
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_ENABLED = "isEnabled";
+ static final private HashSet disabledByDefault = new HashSet<>();
+ static {
+ disabledByDefault.add("com.android.messaging"); //We already have sms notifications in the telephony plugin
+ disabledByDefault.add("com.google.android.googlequicksearchbox"); //Google Now notifications re-spawn every few minutes
+ }
- private static final String DATABASE_NAME = "Applications";
- private static final String DATABASE_TABLE = "Applications";
- private static final int DATABASE_VERSION = 1;
+ static final String KEY_PACKAGE_NAME = "packageName";
+ static final String KEY_IS_ENABLED = "isEnabled";
- private final Context ourContext;
- private SQLiteDatabase ourDatabase;
- private DbHelper ourHelper;
+ static final String DATABASE_NAME = "Applications";
+ static final String DATABASE_TABLE = "Applications";
+ static final int DATABASE_VERSION = 2;
+
+ final Context ourContext;
+ SQLiteDatabase ourDatabase;
+ DbHelper ourHelper;
public AppDatabase(Context c) {
ourContext = c;
}
- private static class DbHelper extends SQLiteOpenHelper{
+ private static class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -53,73 +59,57 @@ public class AppDatabase {
@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_ENABLED + " TEXT NOT NULL); ");
+ db.execSQL("CREATE TABLE " + DATABASE_TABLE + "(" + KEY_PACKAGE_NAME + " TEXT PRIMARY KEY NOT NULL, " + KEY_IS_ENABLED + " TEXT NOT NULL); ");
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i2) {
db.execSQL("DROP TABLE IF EXISTS "+ DATABASE_TABLE);
onCreate(db);
-
}
}
- public void open(){
+ public void open() {
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
}
-
- public void close(){
+ public void close() {
ourHelper.close();
}
- public Cursor getAllApplications()
- {
- String[] columns = new String []{KEY_ROW_ID,KEY_NAME,KEY_PACKAGE_NAME,KEY_IS_ENABLED};
- Cursor res = ourDatabase.query(DATABASE_TABLE,columns,null,null,null,null,KEY_NAME);
- return res;
- }
+ public void setEnabled(String packageName, boolean isEnabled) {
+ String[] columns = new String []{KEY_IS_ENABLED};
+ Cursor res = ourDatabase.query(DATABASE_TABLE, columns, KEY_PACKAGE_NAME + " =? ",new String[]{packageName},null,null,null);
- public long create(String appName, String packageName, boolean isEnabled) {
ContentValues cv = new ContentValues();
- cv.put(KEY_NAME, appName);
- cv.put(KEY_PACKAGE_NAME, packageName);
cv.put(KEY_IS_ENABLED, isEnabled?"true":"false");
- return ourDatabase.insert(DATABASE_TABLE, null, cv);
- }
-
- public long update(String packageName, boolean isEnabled) {
- ContentValues cvUpdate = new ContentValues();
- cvUpdate.put(KEY_IS_ENABLED, isEnabled?"true":"false");
- return ourDatabase.update(DATABASE_TABLE,cvUpdate,KEY_PACKAGE_NAME + "=?",new String[]{packageName});
- }
-
- public boolean exists(String packageName) {
- String[] columns = new String []{KEY_ROW_ID};
- Cursor res = ourDatabase.query(DATABASE_TABLE,columns,KEY_PACKAGE_NAME + " =? ",new String[]{packageName},null,null,null);
- int count = res.getCount();
+ if (res.getCount() > 0) {
+ cv.put(KEY_PACKAGE_NAME, packageName);
+ ourDatabase.insert(DATABASE_TABLE, null, cv);
+ } else {
+ ourDatabase.update(DATABASE_TABLE, cv, KEY_PACKAGE_NAME + "=?",new String[]{packageName});
+ }
res.close();
- return (count != 0);
}
- public boolean isEnabled(String packageName){
+ public boolean isEnabled(String packageName) {
String[] columns = new String []{KEY_IS_ENABLED};
Cursor res = ourDatabase.query(DATABASE_TABLE,columns,KEY_PACKAGE_NAME + " =? ",new String[]{packageName},null,null,null);
- boolean result = true; //Apps are enabled by default
+ boolean result;
if (res.getCount() > 0) {
res.moveToFirst();
result = (res.getString(res.getColumnIndex(KEY_IS_ENABLED))).equals("true");
+ } else {
+ result = getDefaultStatus(packageName);
}
res.close();
return result;
}
- public void delete(String packageName){
- ourDatabase.delete(DATABASE_TABLE,KEY_PACKAGE_NAME + " =? ",new String[]{packageName} );
+ private boolean getDefaultStatus(String packageName) {
+ return !disabledByDefault.contains(packageName);
}
-
}
diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationFilterActivity.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationFilterActivity.java
index a355cbe7..6355ad3f 100644
--- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationFilterActivity.java
+++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationFilterActivity.java
@@ -22,142 +22,144 @@ package org.kde.kdeconnect.Plugins.NotificationsPlugin;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.database.Cursor;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.CheckedTextView;
import android.widget.ListView;
import org.kde.kdeconnect.BackgroundService;
+import org.kde.kdeconnect.Helpers.StringsHelper;
import org.kde.kdeconnect_tp.R;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.List;
public class NotificationFilterActivity extends ActionBarActivity {
- private AppDatabase appDatabase;
+ AppDatabase appDatabase;
+
+ static class AppListInfo {
+ String pkg;
+ String name;
+ Drawable icon;
+ boolean isEnabled;
+ }
+
+ AppListInfo[] apps;
+
+ class AppListAdapter extends BaseAdapter {
+
+ @Override
+ public int getCount() {
+ return apps.length;
+ }
+
+ @Override
+ public AppListInfo getItem(int position) {
+ return apps[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View view, ViewGroup parent) {
+ if (view == null) {
+ LayoutInflater inflater = getLayoutInflater();
+ view = inflater.inflate(android.R.layout.simple_list_item_multiple_choice, null, true);
+ }
+ CheckedTextView checkedTextView = (CheckedTextView)view;
+ checkedTextView.setText(apps[position].name);
+ checkedTextView.setCompoundDrawablesWithIntrinsicBounds(apps[position].icon, null, null, null);
+ checkedTextView.setCompoundDrawablePadding((int)(8*getResources().getDisplayMetrics().density));
+
+ return view;
+ }
+
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification_filter);
- final ListView listView = (ListView)findViewById(R.id.lvFilterApps);
- appDatabase = new AppDatabase(this);
+ appDatabase = new AppDatabase(NotificationFilterActivity.this);
- deleteUninstalledApps();
- addNewlyInstalledApps();
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
- appDatabase.open();
- Cursor res = appDatabase.getAllApplications();
- res.moveToFirst();
+ PackageManager packageManager = getPackageManager();
+ List appList = packageManager.getInstalledApplications(0);
+ int count = appList.size();
- String[] appName = new String[res.getCount()];
- final String[] pkgName = new String[res.getCount()];
- Boolean[] isFiltered = new Boolean[res.getCount()];
+ apps = new AppListInfo[count];
+ appDatabase.open();
+ for (int i = 0; i < count; i++) {
+ ApplicationInfo appInfo = appList.get(i);
+ apps[i] = new AppListInfo();
+ apps[i].pkg = appInfo.packageName;
+ apps[i].name = appInfo.loadLabel(packageManager).toString();
+ apps[i].icon = resizeIcon(appInfo.loadIcon(packageManager), 48);
+ apps[i].isEnabled = appDatabase.isEnabled(appInfo.packageName);
+ }
+ appDatabase.close();
- int i = 0;
- while(!res.isAfterLast()){
- appName[i] = res.getString(res.getColumnIndex(AppDatabase.KEY_NAME));
- pkgName[i] = res.getString(res.getColumnIndex(AppDatabase.KEY_PACKAGE_NAME));
- isFiltered[i] = res.getString(res.getColumnIndex(AppDatabase.KEY_IS_ENABLED)).equals("true");
- res.moveToNext();
- i++;
- }
- res.close();
- appDatabase.close();
+ Arrays.sort(apps, new Comparator() {
+ @Override
+ public int compare(AppListInfo lhs, AppListInfo rhs) {
+ return StringsHelper.compare(lhs.name, rhs.name);
+ }
+ });
- ArrayAdapter adapter = new ArrayAdapter<>(this,
- android.R.layout.simple_list_item_multiple_choice, android.R.id.text1, appName);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ displayAppList();
+ }
+ });
+ }
+ }).start();
+
+ }
+
+ void displayAppList() {
+
+ final ListView listView = (ListView) findViewById(R.id.lvFilterApps);
+ AppListAdapter adapter = new AppListAdapter();
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- for (i = 0 ; i < isFiltered.length; i++){
- if (isFiltered[i]) {
- listView.setItemChecked(i, true);
- }
- }
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
boolean checked = listView.isItemChecked(i);
- //Log.e("NotificationFilterActivity", pkgName[i] + ":" + checked);
appDatabase.open();
- appDatabase.update(pkgName[i], checked);
+ appDatabase.setEnabled(apps[i].pkg, checked);
appDatabase.close();
+ apps[i].isEnabled = checked;
}
});
- }
-
- // 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()) {
- String packageName = res.getString(res.getColumnIndex(AppDatabase.KEY_PACKAGE_NAME));
- if (!isPackageInstalled(packageName)) {
- appDatabase.delete(packageName);
- }
- res.moveToNext();
- }
- res.close();
- }
- 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);
-
- String appName = PackInfo.loadLabel(getPackageManager()).toString();
- String packageName = PackInfo.packageName;
-
- if ( (PackInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0 ) {
-
- if (!appDatabase.exists(packageName)) {
- appDatabase.create(appName, packageName, true);
- }
- //Log.e("App FLAG_UPDATED_SYSTEM_APP: " + Integer.toString(i), appName);
-
- } else if ( (PackInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-
- //ignore these apps
-
- } else {
-
- if (!appDatabase.exists(packageName)) {
- appDatabase.create(appName, packageName, true);
- }
- //Log.e("App : " + Integer.toString(i), appName);
-
- }
+ for (int i = 0 ; i < apps.length; i++) {
+ listView.setItemChecked(i, apps[i].isEnabled);
}
- appDatabase.close();
+ listView.setVisibility(View.VISIBLE);
+ findViewById(R.id.spinner).setVisibility(View.GONE);
}
- private boolean isPackageInstalled(String packageName){
- PackageManager pm = getPackageManager();
- try {
- pm.getPackageInfo(packageName, PackageManager.GET_META_DATA);
- } catch (Exception e) {
- return false;
- }
- return true;
- }
-
@Override
protected void onStart() {
super.onStart();
@@ -170,4 +172,19 @@ public class NotificationFilterActivity extends ActionBarActivity {
BackgroundService.removeGuiInUseCounter(this);
}
+ Drawable resizeIcon(Drawable icon, int maxSize) {
+ Resources res = getResources();
+
+ //Convert to display pixels
+ maxSize = (int)(maxSize*res.getDisplayMetrics().density);
+
+ Bitmap bitmap = Bitmap.createBitmap(maxSize, maxSize, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ icon.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ icon.draw(canvas);
+
+ return new BitmapDrawable(res, bitmap);
+
+
+ }
}
diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
index f30707f0..3feb2f36 100644
--- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
+++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
@@ -170,11 +170,6 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
return;
}
- if (packageName.equals("com.google.android.googlequicksearchbox")) {
- //HACK: Hide Google Now notifications that keep constantly popping up (and without text because we don't know how to read them properly)
- return;
- }
-
NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_NOTIFICATION);
if (packageName.equals("org.kde.kdeconnect_tp"))