Merge branch 'filter_app' into stom79_baseline

# Conflicts:
#	app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java
#	app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/AppListFragment.java
This commit is contained in:
stom79 2018-04-14 14:44:28 +02:00
commit d81078659a
13 changed files with 109 additions and 20 deletions

View File

@ -19,11 +19,16 @@
package org.eu.exodus_privacy.exodusprivacy; package org.eu.exodus_privacy.exodusprivacy;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.app.SearchManager;
import android.content.Context;
import android.databinding.DataBindingUtil; import android.databinding.DataBindingUtil;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; 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.adapters.ApplicationListAdapter;
import org.eu.exodus_privacy.exodusprivacy.databinding.MainBinding; import org.eu.exodus_privacy.exodusprivacy.databinding.MainBinding;
@ -94,4 +99,30 @@ public class MainActivity extends AppCompatActivity {
else else
getSupportFragmentManager().popBackStack(); getSupportFragmentManager().popBackStack();
} }
@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;
}
} }

View File

@ -22,32 +22,33 @@ import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.databinding.DataBindingUtil; import android.databinding.DataBindingUtil;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; 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.R;
import org.eu.exodus_privacy.exodusprivacy.databinding.AppItemBinding; import org.eu.exodus_privacy.exodusprivacy.databinding.AppItemBinding;
import org.eu.exodus_privacy.exodusprivacy.manager.DatabaseManager; import org.eu.exodus_privacy.exodusprivacy.manager.DatabaseManager;
import org.eu.exodus_privacy.exodusprivacy.objects.Report; import org.eu.exodus_privacy.exodusprivacy.objects.Report;
import org.eu.exodus_privacy.exodusprivacy.objects.Tracker; import org.eu.exodus_privacy.exodusprivacy.objects.Tracker;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
public class ApplicationListAdapter extends android.support.v7.widget.RecyclerView.Adapter<ApplicationListAdapter.ApplicationListViewHolder>{ public class ApplicationListAdapter extends RecyclerView.Adapter {
private List<PackageInfo> packages; private List<PackageInfo> packages;
private PackageManager packageManager; private PackageManager packageManager;
private OnAppClickListener onAppClickListener; private OnAppClickListener onAppClickListener;
private static final String gStore = "com.android.vending"; 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<PackageInfo> alphaPackageComparator = new Comparator<PackageInfo>() { private Comparator<PackageInfo> alphaPackageComparator = new Comparator<PackageInfo>() {
@Override @Override
@ -66,13 +67,13 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi
private void setInstalledPackages(List<PackageInfo> installedPackages) { private void setInstalledPackages(List<PackageInfo> installedPackages) {
packages = installedPackages; packages = installedPackages;
applyStoreFilter(); applyStoreFilter();
Collections.sort(packages,alphaPackageComparator); Collections.sort(packages, alphaPackageComparator);
notifyDataSetChanged(); notifyDataSetChanged();
} }
private void applyStoreFilter() { private void applyStoreFilter() {
List<PackageInfo> toRemove = new ArrayList<>(); List<PackageInfo> toRemove = new ArrayList<>();
for(PackageInfo pkg : packages) { for (PackageInfo pkg : packages) {
if (!gStore.equals(packageManager.getInstallerPackageName(pkg.packageName))) { if (!gStore.equals(packageManager.getInstallerPackageName(pkg.packageName))) {
toRemove.add(pkg); toRemove.add(pkg);
} }
@ -81,22 +82,40 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi
} }
@Override @Override
public ApplicationListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public int getItemViewType(int position){
AppItemBinding appItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),R.layout.app_item,parent,false); return (Pattern.compile(Pattern.quote(filter.trim()), Pattern.CASE_INSENSITIVE).matcher(packageManager.getApplicationLabel(packages.get(position).applicationInfo)).find())?DISPLAYED_APP:HIDDEN_APP;
return new ApplicationListViewHolder(appItemBinding); }
@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 @Override
public void onBindViewHolder(ApplicationListViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
holder.setData(packages.get(position)); if( viewHolder.getItemViewType() == DISPLAYED_APP) {
holder.itemView.setOnClickListener(new View.OnClickListener() { final ApplicationListViewHolder holder = (ApplicationListViewHolder) viewHolder;
@Override holder.setData(packages.get(position));
public void onClick(View v) { //noinspection Convert2Lambda
onAppClickListener.onAppClick(holder.packageInfo); 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 @Override
public int getItemCount() { public int getItemCount() {
return packages.size(); 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 { class ApplicationListViewHolder extends RecyclerView.ViewHolder {
PackageInfo packageInfo; PackageInfo packageInfo;
@ -168,4 +194,10 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi
public interface OnAppClickListener { public interface OnAppClickListener {
void onAppClick(PackageInfo packageInfo); void onAppClick(PackageInfo packageInfo);
} }
public void filter(String text) {
filter = text;
notifyDataSetChanged();
}
} }

View File

@ -48,6 +48,7 @@ public class AppListFragment extends Fragment {
private ApplicationListAdapter.OnAppClickListener onAppClickListener; private ApplicationListAdapter.OnAppClickListener onAppClickListener;
private boolean startupRefresh; private boolean startupRefresh;
private ApplistBinding applistBinding; private ApplistBinding applistBinding;
private ApplicationListAdapter adapter;
public static AppListFragment newInstance(NetworkListener networkListener, ApplicationListAdapter.OnAppClickListener appClickListener) { public static AppListFragment newInstance(NetworkListener networkListener, ApplicationListAdapter.OnAppClickListener appClickListener) {
AppListFragment fragment = new AppListFragment(); AppListFragment fragment = new AppListFragment();
@ -86,7 +87,7 @@ public class AppListFragment extends Fragment {
} }
applistBinding.noPackageManager.setVisibility(View.GONE); applistBinding.noPackageManager.setVisibility(View.GONE);
applistBinding.noAppFound.setVisibility(View.GONE); applistBinding.noAppFound.setVisibility(View.GONE);
ApplicationListAdapter adapter = new ApplicationListAdapter(packageManager, onAppClickListener); adapter = new ApplicationListAdapter(packageManager, onAppClickListener);
if(adapter.getItemCount() == 0) { if(adapter.getItemCount() == 0) {
applistBinding.noAppFound.setVisibility(View.VISIBLE); applistBinding.noAppFound.setVisibility(View.VISIBLE);
} else { } else {
@ -170,4 +171,8 @@ public class AppListFragment extends Fragment {
super.onDetach(); super.onDetach();
packageManager = null; packageManager = null;
} }
public void filter(String filter){
adapter.filter(filter);
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_filter"
android:icon="@drawable/ic_search"
android:title="@string/menu_action_filter"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView" />
</menu>

View File

@ -20,4 +20,7 @@
<string name="parse_trackers">Traitement des pisteurs :</string> <string name="parse_trackers">Traitement des pisteurs :</string>
<string name="get_trackers_connection">Récupération des pisteurs : en attente de connexion au serveur</string> <string name="get_trackers_connection">Récupération des pisteurs : en attente de connexion au serveur</string>
<string name="get_trackers">Récupération des pisteurs</string> <string name="get_trackers">Récupération des pisteurs</string>
<!-- Menu -->
<string name="menu_action_filter">Filtrer</string>
</resources> </resources>

View File

@ -20,4 +20,7 @@
<string name="parse_trackers">Processing Trackers:</string> <string name="parse_trackers">Processing Trackers:</string>
<string name="get_trackers_connection">Getting trackers: Waiting for server connection</string> <string name="get_trackers_connection">Getting trackers: Waiting for server connection</string>
<string name="get_trackers">Getting trackers</string> <string name="get_trackers">Getting trackers</string>
<!-- Menu -->
<string name="menu_action_filter">Filter</string>
</resources> </resources>