From 8271f785c7b649bf1a8a72bc4e0eac7fe934a85a Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Sun, 21 Jun 2015 14:20:15 +0200 Subject: Implement searching in allowed Apps, closes #362 --- .../openvpn/fragments/Settings_Allowed_Apps.java | 114 +++++++++++++++++++-- .../res/drawable-hdpi/ic_search_white_24dp.png | Bin 0 -> 396 bytes .../res/drawable-mdpi/ic_search_white_24dp.png | Bin 0 -> 247 bytes .../res/drawable-xhdpi/ic_search_white_24dp.png | Bin 0 -> 465 bytes .../res/drawable-xxhdpi/ic_search_white_24dp.png | Bin 0 -> 728 bytes .../res/drawable-xxxhdpi/ic_search_white_24dp.png | Bin 0 -> 915 bytes main/src/main/res/menu/allowed_apps.xml | 14 +++ main/src/main/res/values/strings.xml | 1 + 8 files changed, 121 insertions(+), 8 deletions(-) create mode 100755 main/src/main/res/drawable-hdpi/ic_search_white_24dp.png create mode 100755 main/src/main/res/drawable-mdpi/ic_search_white_24dp.png create mode 100755 main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png create mode 100755 main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png create mode 100755 main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png create mode 100644 main/src/main/res/menu/allowed_apps.xml diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.java index a1635d54..c6c7996c 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Allowed_Apps.java @@ -7,6 +7,7 @@ package de.blinkt.openvpn.fragments; import android.Manifest; import android.app.Fragment; +import android.app.SearchManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -14,16 +15,22 @@ import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.CompoundButton; +import android.widget.Filter; +import android.widget.Filterable; import android.widget.ImageView; import android.widget.ListView; +import android.widget.SearchView; import android.widget.Switch; import android.widget.TextView; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; @@ -35,7 +42,7 @@ import de.blinkt.openvpn.core.ProfileManager; /** * Created by arne on 16.11.14. */ -public class Settings_Allowed_Apps extends Fragment implements AdapterView.OnItemClickListener, CompoundButton.OnCheckedChangeListener { +public class Settings_Allowed_Apps extends Fragment implements AdapterView.OnItemClickListener, CompoundButton.OnCheckedChangeListener, View.OnClickListener { private ListView mListView; private VpnProfile mProfile; private TextView mDefaultAllowTextView; @@ -47,6 +54,11 @@ public class Settings_Allowed_Apps extends Fragment implements AdapterView.OnIte avh.checkBox.toggle(); } + @Override + public void onClick(View v) { + + } + static class AppViewHolder { public ApplicationInfo mInfo; public View rootView; @@ -96,10 +108,59 @@ public class Settings_Allowed_Apps extends Fragment implements AdapterView.OnIte } - class PackageAdapter extends BaseAdapter { + class PackageAdapter extends BaseAdapter implements Filterable { private final List mPackages; private final LayoutInflater mInflater; private final PackageManager mPm; + private ItemFilter mFilter = new ItemFilter(); + private Vector mFilteredData; + + + private class ItemFilter extends Filter { + @Override + protected FilterResults performFiltering(CharSequence constraint) { + + String filterString = constraint.toString().toLowerCase(); + + FilterResults results = new FilterResults(); + + + int count = mPackages.size(); + final Vector nlist = new Vector<>(count); + + String filterableString ; + + + + for (int i = 0; i < count; i++) { + ApplicationInfo pInfo = mPackages.get(i); + CharSequence appName = pInfo.loadLabel(mPm); + + if (TextUtils.isEmpty(appName)) + appName = pInfo.packageName; + + if (appName instanceof String) { + if (((String) appName).toLowerCase().contains(filterString)) + nlist.add(pInfo); + } else { + if (appName.toString().toLowerCase().contains(filterString)) + nlist.add(pInfo); + } + } + results.values = nlist; + results.count = nlist.size(); + + return results; + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + mFilteredData = (Vector) results.values; + notifyDataSetChanged(); + } + + } + PackageAdapter(Context c, VpnProfile vp) { mPm = c.getPackageManager(); @@ -132,29 +193,30 @@ public class Settings_Allowed_Apps extends Fragment implements AdapterView.OnIte Collections.sort(apps, new ApplicationInfo.DisplayNameComparator(mPm)); mPackages = apps; + mFilteredData = apps; } @Override public int getCount() { - return mPackages.size(); + return mFilteredData.size(); } @Override public Object getItem(int position) { - return mPackages.get(position); + return mFilteredData.get(position); } @Override public long getItemId(int position) { - return mPackages.get(position).packageName.hashCode(); + return mFilteredData.get(position).packageName.hashCode(); } @Override public View getView(int position, View convertView, ViewGroup parent) { - AppViewHolder viewHolder = AppViewHolder.createOrRecycle(mInflater, convertView ,parent); + AppViewHolder viewHolder = AppViewHolder.createOrRecycle(mInflater, convertView, parent); convertView = viewHolder.rootView; - viewHolder.mInfo = mPackages.get(position); - final ApplicationInfo mInfo = mPackages.get(position); + viewHolder.mInfo = mFilteredData.get(position); + final ApplicationInfo mInfo = mFilteredData.get(position); CharSequence appName = mInfo.loadLabel(mPm); @@ -170,6 +232,11 @@ public class Settings_Allowed_Apps extends Fragment implements AdapterView.OnIte viewHolder.checkBox.setChecked(mProfile.mAllowedAppsVpn.contains(mInfo.packageName)); return viewHolder.rootView; } + + @Override + public Filter getFilter() { + return mFilter; + } } @Override @@ -185,7 +252,38 @@ public class Settings_Allowed_Apps extends Fragment implements AdapterView.OnIte String profileUuid = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); mProfile = ProfileManager.get(getActivity(), profileUuid); getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName())); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.allowed_apps, menu); + + SearchView searchView = (SearchView) menu.findItem( R.id.app_search_widget ).getActionView(); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + mListView.setFilterText(query); + mListView.setTextFilterEnabled(true); + return true; + } + + @Override + public boolean onQueryTextChange(String newText) { + mListView.setFilterText(newText); + mListView.setTextFilterEnabled(true); + return true; + } + }); + searchView.setOnCloseListener(new SearchView.OnCloseListener() { + @Override + public boolean onClose() { + mListView.setTextFilterEnabled(false); + return false; + } + }); + super.onCreateOptionsMenu(menu, inflater); } @Override diff --git a/main/src/main/res/drawable-hdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-hdpi/ic_search_white_24dp.png new file mode 100755 index 00000000..bbfbc96c Binary files /dev/null and b/main/src/main/res/drawable-hdpi/ic_search_white_24dp.png differ diff --git a/main/src/main/res/drawable-mdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-mdpi/ic_search_white_24dp.png new file mode 100755 index 00000000..faefc59c Binary files /dev/null and b/main/src/main/res/drawable-mdpi/ic_search_white_24dp.png differ diff --git a/main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png new file mode 100755 index 00000000..bfc3e393 Binary files /dev/null and b/main/src/main/res/drawable-xhdpi/ic_search_white_24dp.png differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png new file mode 100755 index 00000000..abbb9895 Binary files /dev/null and b/main/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png differ diff --git a/main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png b/main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png new file mode 100755 index 00000000..dd5adfc7 Binary files /dev/null and b/main/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png differ diff --git a/main/src/main/res/menu/allowed_apps.xml b/main/src/main/res/menu/allowed_apps.xml new file mode 100644 index 00000000..d4f2a02a --- /dev/null +++ b/main/src/main/res/menu/allowed_apps.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml index 6e2e04ca..1c474145 100755 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -382,5 +382,6 @@ Certificate Revocation List Restarting OpenVPN Service (App crashed probably crashed or killed for memory pressure) Importing the config yielded an error, cannot save it + Search -- cgit v1.2.3