From 37050d78fc19e3d240ec937c9d9dacd56f95ae7c Mon Sep 17 00:00:00 2001 From: stom79 Date: Sat, 14 Apr 2018 14:37:51 +0200 Subject: [PATCH 1/2] Add app filter in top bar --- .../exodusprivacy/MainActivity.java | 31 ++++++++ .../adapters/ApplicationListAdapter.java | 70 +++++++++++++----- .../fragments/AppListFragment.java | 12 +-- app/src/main/res/drawable-hdpi/ic_search.png | Bin 0 -> 448 bytes app/src/main/res/drawable-ldpi/ic_search.png | Bin 0 -> 384 bytes app/src/main/res/drawable-mdpi/ic_search.png | Bin 0 -> 265 bytes app/src/main/res/drawable-xhdpi/ic_search.png | Bin 0 -> 492 bytes .../main/res/drawable-xxhdpi/ic_search.png | Bin 0 -> 744 bytes .../main/res/drawable-xxxhdpi/ic_search.png | Bin 0 -> 967 bytes app/src/main/res/layout/app_item_empty.xml | 5 ++ app/src/main/res/menu/main.xml | 10 +++ app/src/main/res/values-fr/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 13 files changed, 109 insertions(+), 25 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_search.png create mode 100644 app/src/main/res/drawable-ldpi/ic_search.png create mode 100644 app/src/main/res/drawable-mdpi/ic_search.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_search.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_search.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_search.png create mode 100644 app/src/main/res/layout/app_item_empty.xml create mode 100644 app/src/main/res/menu/main.xml diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java index 82aa28c..0984781 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java @@ -20,10 +20,15 @@ package org.eu.exodus_privacy.exodusprivacy; import android.app.FragmentManager; import android.app.FragmentTransaction; +import android.app.SearchManager; +import android.content.Context; import android.databinding.DataBindingUtil; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.support.v7.widget.SearchView; +import android.view.Menu; +import android.view.MenuInflater; import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationListAdapter; import org.eu.exodus_privacy.exodusprivacy.databinding.MainBinding; @@ -92,4 +97,30 @@ public class MainActivity extends AppCompatActivity { if(report != null) report = null; } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main, menu); + SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); + SearchView searchView = (SearchView) menu.findItem(R.id.action_filter).getActionView(); + assert searchManager != null; + searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); + searchView.setIconifiedByDefault(false); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + appList.filter(query); + return true; + } + + @Override + public boolean onQueryTextChange(String newText) { + appList.filter(newText); + return true; + } + }); + return true; + } } diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/ApplicationListAdapter.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/ApplicationListAdapter.java index 946dbe9..6655aef 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/ApplicationListAdapter.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/ApplicationListAdapter.java @@ -22,32 +22,33 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.databinding.DataBindingUtil; +import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - import org.eu.exodus_privacy.exodusprivacy.R; import org.eu.exodus_privacy.exodusprivacy.databinding.AppItemBinding; import org.eu.exodus_privacy.exodusprivacy.manager.DatabaseManager; import org.eu.exodus_privacy.exodusprivacy.objects.Report; import org.eu.exodus_privacy.exodusprivacy.objects.Tracker; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.regex.Pattern; -public class ApplicationListAdapter extends android.support.v7.widget.RecyclerView.Adapter{ +public class ApplicationListAdapter extends RecyclerView.Adapter { private List packages; private PackageManager packageManager; private OnAppClickListener onAppClickListener; private static final String gStore = "com.android.vending"; + private String filter = ""; + private final int HIDDEN_APP = 0; + private final int DISPLAYED_APP = 1; + private Comparator alphaPackageComparator = new Comparator() { @Override @@ -66,13 +67,13 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi private void setInstalledPackages(List installedPackages) { packages = installedPackages; applyStoreFilter(); - Collections.sort(packages,alphaPackageComparator); + Collections.sort(packages, alphaPackageComparator); notifyDataSetChanged(); } private void applyStoreFilter() { List toRemove = new ArrayList<>(); - for(PackageInfo pkg : packages) { + for (PackageInfo pkg : packages) { if (!gStore.equals(packageManager.getInstallerPackageName(pkg.packageName))) { toRemove.add(pkg); } @@ -81,22 +82,40 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi } @Override - public ApplicationListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - AppItemBinding appItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),R.layout.app_item,parent,false); - return new ApplicationListViewHolder(appItemBinding); + public int getItemViewType(int position){ + return (Pattern.compile(Pattern.quote(filter.trim()), Pattern.CASE_INSENSITIVE).matcher(packageManager.getApplicationLabel(packages.get(position).applicationInfo)).find())?DISPLAYED_APP:HIDDEN_APP; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if( viewType == HIDDEN_APP) + return new ApplicationEmptyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.app_item_empty, parent, false)); + else + return new ApplicationListViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.app_item, parent, false)); + } @Override - public void onBindViewHolder(ApplicationListViewHolder holder, int position) { - holder.setData(packages.get(position)); - holder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onAppClickListener.onAppClick(holder.packageInfo); - } - }); + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { + if( viewHolder.getItemViewType() == DISPLAYED_APP) { + final ApplicationListViewHolder holder = (ApplicationListViewHolder) viewHolder; + holder.setData(packages.get(position)); + //noinspection Convert2Lambda + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onAppClickListener.onAppClick(holder.packageInfo); + } + }); + }else { + //noinspection unused + final ApplicationEmptyViewHolder holder = (ApplicationEmptyViewHolder) viewHolder; + //If something should be done for app that are hidden, it's here + } } + @Override public int getItemCount() { return packages.size(); @@ -110,6 +129,13 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi } } + class ApplicationEmptyViewHolder extends RecyclerView.ViewHolder{ + ApplicationEmptyViewHolder(View itemView) { + super(itemView); + } + } + + class ApplicationListViewHolder extends RecyclerView.ViewHolder { PackageInfo packageInfo; @@ -168,4 +194,10 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi public interface OnAppClickListener { void onAppClick(PackageInfo packageInfo); } + + + public void filter(String text) { + filter = text; + notifyDataSetChanged(); + } } diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/AppListFragment.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/AppListFragment.java index 5a674ff..9ad297f 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/AppListFragment.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/AppListFragment.java @@ -26,15 +26,10 @@ import android.content.pm.PackageManager; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.annotation.Nullable; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; import org.eu.exodus_privacy.exodusprivacy.R; import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationListAdapter; @@ -53,6 +48,7 @@ public class AppListFragment extends Fragment { private ApplicationListAdapter.OnAppClickListener onAppClickListener; private boolean startupRefresh; private ApplistBinding applistBinding; + private ApplicationListAdapter adapter; public static AppListFragment newInstance(NetworkListener networkListener, ApplicationListAdapter.OnAppClickListener appClickListener) { AppListFragment fragment = new AppListFragment(); @@ -91,7 +87,7 @@ public class AppListFragment extends Fragment { } applistBinding.noPackageManager.setVisibility(View.GONE); applistBinding.noAppFound.setVisibility(View.GONE); - ApplicationListAdapter adapter = new ApplicationListAdapter(packageManager, onAppClickListener); + adapter = new ApplicationListAdapter(packageManager, onAppClickListener); if(adapter.getItemCount() == 0) { applistBinding.noAppFound.setVisibility(View.VISIBLE); } else { @@ -175,4 +171,8 @@ public class AppListFragment extends Fragment { super.onDetach(); packageManager = null; } + + public void filter(String filter){ + adapter.filter(filter); + } } diff --git a/app/src/main/res/drawable-hdpi/ic_search.png b/app/src/main/res/drawable-hdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..c53e3315c06a96e7a0311a8655924065a195636d GIT binary patch literal 448 zcmV;x0YCnUP) qKMb@-9qed_@(-<%#V7j+Dy~mrwlC~vGhU$p0000y3MC_V;GkVg2QHwlpg43Wb_=DnE9fNR$kLevsY+>altqMo z2VOynyhPN%Avf>5e7QeKN~KdB#u%xNnkYaGRNe~`MUj^z$z__R_vi_|q5*3iyxKmH zn=H%b=nKFMO^Da%6Yq{aer`F+#6muZyWC_@NPG?Oh4m%zEqgr|sIGF9iG`ePKZNTm z{5g77-&~-k?a54;?C=|SBeXIiJ3xVL>_p}4@O``?TIYfE#DN;Cp8Ven`~rW9-ta;f zsH_odI%=$XV&5NM5WEMx4PKA6^StrbG-6H1Hg;sonF@k_i2Lko6?vC@jabuBW7QLt zqf7(=w!nX6U%SXB;@MB*?+8_nG7$vWcVU<#>d literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_search.png b/app/src/main/res/drawable-mdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..5feb851bd766a9c5f9fb4652ba88abeb6e70797a GIT binary patch literal 265 zcmV+k0rvihP)M=qJV0%oIN_h&L;~PN-N61&hfFozStU1Ur&7 zI$>nd63iwWOkZ#XJCU_Ip=2=27^?%A^i=wD(5oSg0_}za2|KQh29jO~P P00000NkvXXu0mjf?apZ5 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_search.png b/app/src/main/res/drawable-xhdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..3b174553ebe8da1fefc56363804de6c02dd3034c GIT binary patch literal 492 zcmV-Ji<&Jc+N?G zjdxh-4Lo?a3P2cdPfMkDs+SMf#|Q+80NgaEjP6XJ>$~Q;l+@9lH!0@ z-uugw9xtzAD!%RyV;?p3#d!^3F+h{Tx|Ys9IqPD8F@>cqoe$(3hym6V7O-@N$hi~) zY$?oX>2#BGBL{H(8L*QZqM)VohMX%gz=*;!md-3WM`C~mh4n0*PvoqL0U~?@#Y}w( z?zT$#yV`ts%#Z)ljM7};OD<8vUMaeHB3MGnOfaHW%=)m zFzOg!i4AsGv3*|CE*SQ%sifw+uc{tV(IJXz5M>>rpaxOWA@b@GIW>r)dPG4nfFbfq i(|;p!O4Hl2rB0s>&iunp$-!y>0000 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_search.png b/app/src/main/res/drawable-xxhdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..c635b4a5337e84f4dbeea17eb4ab73eb60277a21 GIT binary patch literal 744 zcmVP)`bXBnrASUPoh$skwzK7r?1+kZaYZV_r6kMq2Lb|L* zF<$7RDk6x&`0v-&mhYSy(mBI7nJJtp1^4jJJ(khmNSW8z!N0SG-bTng!5o6-0cAMR>U84^%(92B=yYD- z6y~WRAJxU^gGEFg~-r0A8WRX2|dAElhU&Qs4|oni!OpO$Hi;>{D6eeEbDMC1pkro(-J~!tiwVGeu(j_5<(}e z!w^*oFByLI=l$6Q(rNDP(r9fsb!;v^te*X+GNV>GVAmVSp%{S-x#|jb^Pd8 zPBotm$OVObBX>mGRyr;Pq~0mihU5{pS34h<0_kwZ#Vgrk{(J2fQK>hVXzna%?I)$L zK@Q!m)ST04(D7|Ku1w{h*)`oRf+%$G(B7#UVo_G)wQpv<+VQT&F8&j^Z+% z_fay*5xV7{(w?Eju5uMRlvi?4R#s2FxR|7yezWpjRa}XrdaxNlXXDR8*S@bt@{bYv zut>GZKX+K-yE4t4Mkvt_wPOI&Sj91}X?SkweH~L6)JrIyH%!Uk&#psF=^%+pxww_8 zRw=;7sw?fsuXNy1>avw(Yd)3$00001VZ_^L*N$}O+!Oe2tf?! zRrv}Ygr+qiQ9e@g_y#eCnc3Rz?o2y4&t5j$-DjR>cV^yq-l=677#J8B7#J8BI0VYk ziV4K9i3CpQNYL3lU1>#GzDuvdFuo!kb}@v?e3X6#O;|>zSVCid$-j+NWQ!G4=ZE-0 zL~sfxIK?Omb1lCNAK?b;D9xq(d-x8wNTM!R@*m(3Uf?J0=jQF(%l|^-B8W;9p@5De zItyYP8)+=uQQ!B)ohOB9)Yv{%iy68@+>um{1zg1^p^TR($-w$+;j?S-sWT7}2>5}P zjGuo(orcGVy0FF1``_TtiX(tML0qU(lQgUf<#>bMtwz%Ey&T{F%yj5~4{i!5qf zbJlU3@?tWrYA@omC#;(cYe=4f38txtC#;hU>zF(PF{Y`YC#;Vc)~GxK?8o+`zCdZk zMQq43kYJiB@`SaRVU5c(aKbcI;0ddbVLjH}KuY&6bfEhn-jruxUdlAu%&;z~3uNP- zuud_oQ|eL)4`ysy;ccl)CCa$OtJXE=U5>L{W}V!%%~A{032Xf42{9&VsUDzA-$zF=oi$U+ zwv}d|EQN=bYM?%i1?L!0`xTNNY_qb}(SEgKVa=8N54esXcU7qcA4VMh)gXlzzc=;- zzlGI~hCmkoRQZEO(*ddHjRNkO`=a_o>0mX#{iUT40IE{h4vf#+JorNBKEcEMdA#7uzTYn2(`dH|@ zycRn3vCyl(g&rFV9r{~n*T+Kl<+aeJkA*J%Ep%#bKxjcH`DYe7w3g3U&{6)Gg?6pw ppIK + \ No newline at end of file diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml new file mode 100644 index 0000000..2846266 --- /dev/null +++ b/app/src/main/res/menu/main.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b3336f9..776ff53 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -20,4 +20,7 @@ Traitement des pisteurs : Récupération des pisteurs : en attente de connexion au serveur Récupération des pisteurs + + + Filtrer diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d5e9aa8..9e2a02e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,4 +20,7 @@ Processing Trackers: Getting trackers: Waiting for server connection Getting trackers + + + Filter From 543941fc943bc378e20e871fa5a91bdffefda67e Mon Sep 17 00:00:00 2001 From: stom79 Date: Sat, 14 Apr 2018 15:29:39 +0200 Subject: [PATCH 2/2] Remove filter in reports --- .../exodusprivacy/MainActivity.java | 17 ++++++++++++----- .../exodusprivacy/fragments/ReportFragment.java | 13 +++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java index 0984781..faa18a7 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java @@ -20,7 +20,6 @@ package org.eu.exodus_privacy.exodusprivacy; import android.app.FragmentManager; import android.app.FragmentTransaction; -import android.app.SearchManager; import android.content.Context; import android.databinding.DataBindingUtil; import android.support.design.widget.Snackbar; @@ -29,6 +28,7 @@ import android.os.Bundle; import android.support.v7.widget.SearchView; import android.view.Menu; import android.view.MenuInflater; +import android.view.inputmethod.InputMethodManager; import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationListAdapter; import org.eu.exodus_privacy.exodusprivacy.databinding.MainBinding; @@ -40,6 +40,8 @@ public class MainActivity extends AppCompatActivity { AppListFragment appList; ReportFragment report; + SearchView searchView; + private Menu mMenu; @Override protected void onCreate(Bundle savedInstanceState) { @@ -80,6 +82,13 @@ public class MainActivity extends AppCompatActivity { transaction.addToBackStack(null); transaction.replace(R.id.fragment_container,report); transaction.commit(); + searchView.clearFocus(); + if (mMenu != null) + (mMenu.findItem(R.id.action_filter)).collapseActionView(); + InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); + assert imm != null; + imm.hideSoftInputFromWindow(mainBinding.fragmentContainer.getWindowToken(), 0); + }; appList = AppListFragment.newInstance(networkListener,onAppClickListener); @@ -101,12 +110,10 @@ public class MainActivity extends AppCompatActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { + mMenu = menu; MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); - SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); - SearchView searchView = (SearchView) menu.findItem(R.id.action_filter).getActionView(); - assert searchManager != null; - searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); + searchView = (SearchView) menu.findItem(R.id.action_filter).getActionView(); searchView.setIconifiedByDefault(false); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/ReportFragment.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/ReportFragment.java index 2bd26c3..9754f0e 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/ReportFragment.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/ReportFragment.java @@ -28,11 +28,10 @@ import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.webkit.WebView; -import android.widget.ImageView; -import android.widget.TextView; import org.eu.exodus_privacy.exodusprivacy.R; import org.eu.exodus_privacy.exodusprivacy.adapters.PermissionListAdapter; @@ -44,7 +43,6 @@ import org.eu.exodus_privacy.exodusprivacy.objects.Report; import org.eu.exodus_privacy.exodusprivacy.objects.Tracker; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Set; @@ -65,6 +63,7 @@ public class ReportFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setHasOptionsMenu(true); } @@ -180,4 +179,10 @@ public class ReportFragment extends Fragment { public void setPackageInfo(PackageInfo packageInfo) { this.packageInfo = packageInfo; } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + MenuItem item = menu.findItem(R.id.action_filter); + item.setVisible(false); + } }