parent
883b623d6d
commit
3b7343bc68
|
@ -1,9 +1,11 @@
|
||||||
package org.eu.exodus_privacy.exodusprivacy;
|
package org.eu.exodus_privacy.exodusprivacy;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
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.content.pm.Signature;
|
import android.content.pm.Signature;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -12,13 +14,21 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public static final String TAG = "Exodus_privacy";
|
public static final String TAG = "Exodus_privacy";
|
||||||
|
|
||||||
|
public static final String APP_PREFS = "app_prefs";
|
||||||
|
public static final String LAST_REFRESH = "last_refresh";
|
||||||
|
|
||||||
@SuppressLint("PackageManagerGetSignatures")
|
@SuppressLint("PackageManagerGetSignatures")
|
||||||
public static String getCertificateSHA1Fingerprint(PackageManager pm, String packageName) {
|
public static String getCertificateSHA1Fingerprint(PackageManager pm, String packageName) {
|
||||||
int flags = PackageManager.GET_SIGNATURES;
|
int flags = PackageManager.GET_SIGNATURES;
|
||||||
|
@ -84,6 +94,47 @@ public class Utils {
|
||||||
return str.toString();
|
return str.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a date in String -> format yyyy-MM-dd HH:mm:ss
|
||||||
|
*
|
||||||
|
* @param date Date
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String dateToString(Date date) {
|
||||||
|
if (date == null)
|
||||||
|
return null;
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
||||||
|
return dateFormat.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert String date from db to Date Object
|
||||||
|
*
|
||||||
|
* @param stringDate date to convert
|
||||||
|
* @return Date
|
||||||
|
*/
|
||||||
|
public static Date stringToDate(Context context, String stringDate) {
|
||||||
|
if (stringDate == null)
|
||||||
|
return null;
|
||||||
|
Locale userLocale;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
userLocale = context.getResources().getConfiguration().getLocales().get(0);
|
||||||
|
} else {
|
||||||
|
userLocale = context.getResources().getConfiguration().locale;
|
||||||
|
}
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", userLocale);
|
||||||
|
Date date = null;
|
||||||
|
try {
|
||||||
|
date = dateFormat.parse(stringDate);
|
||||||
|
} catch (java.text.ParseException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Simple and not complete markdownToHtml converter
|
Simple and not complete markdownToHtml converter
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package org.eu.exodus_privacy.exodusprivacy.fragments;
|
package org.eu.exodus_privacy.exodusprivacy.fragments;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -17,6 +19,7 @@ import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
import org.eu.exodus_privacy.exodusprivacy.R;
|
import org.eu.exodus_privacy.exodusprivacy.R;
|
||||||
|
import org.eu.exodus_privacy.exodusprivacy.Utils;
|
||||||
import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationListAdapter;
|
import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationListAdapter;
|
||||||
import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationViewModel;
|
import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationViewModel;
|
||||||
import org.eu.exodus_privacy.exodusprivacy.databinding.HomeBinding;
|
import org.eu.exodus_privacy.exodusprivacy.databinding.HomeBinding;
|
||||||
|
@ -26,8 +29,12 @@ import org.eu.exodus_privacy.exodusprivacy.manager.NetworkManager;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
|
|
||||||
public class HomeFragment extends Fragment implements ComputeAppListTask.Listener, Updatable {
|
public class HomeFragment extends Fragment implements ComputeAppListTask.Listener, Updatable {
|
||||||
|
|
||||||
private @Nullable
|
private @Nullable
|
||||||
|
@ -45,6 +52,8 @@ public class HomeFragment extends Fragment implements ComputeAppListTask.Listene
|
||||||
private int lastProgress = 0;
|
private int lastProgress = 0;
|
||||||
private int lastMaxProgress = 0;
|
private int lastMaxProgress = 0;
|
||||||
private int scrollTo = 0;
|
private int scrollTo = 0;
|
||||||
|
private String last_refresh;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
if (applications == null)
|
if (applications == null)
|
||||||
|
@ -59,18 +68,24 @@ public class HomeFragment extends Fragment implements ComputeAppListTask.Listene
|
||||||
Context context = homeBinding.getRoot().getContext();
|
Context context = homeBinding.getRoot().getContext();
|
||||||
packageManager = context.getPackageManager();
|
packageManager = context.getPackageManager();
|
||||||
homeBinding.swipeRefresh.setOnRefreshListener(this::startRefresh);
|
homeBinding.swipeRefresh.setOnRefreshListener(this::startRefresh);
|
||||||
|
|
||||||
|
SharedPreferences sharedPreferences = getContext().getSharedPreferences(Utils.APP_PREFS, MODE_PRIVATE);
|
||||||
|
last_refresh = sharedPreferences.getString(Utils.LAST_REFRESH, null);
|
||||||
|
|
||||||
if (packageManager != null) {
|
if (packageManager != null) {
|
||||||
homeBinding.noPackageManager.setVisibility(View.GONE);
|
homeBinding.noPackageManager.setVisibility(View.GONE);
|
||||||
|
|
||||||
onAppsComputed(applications);
|
onAppsComputed(applications);
|
||||||
if (applications.isEmpty())
|
if (applications.isEmpty())
|
||||||
displayAppListAsync();
|
displayAppListAsync();
|
||||||
if (startRefreshAsked)
|
if (startRefreshAsked && last_refresh == null)
|
||||||
startRefresh();
|
startRefresh();
|
||||||
else if (refreshInProgress) {
|
else if (refreshInProgress) {
|
||||||
homeBinding.layoutProgress.setVisibility(View.VISIBLE);
|
homeBinding.layoutProgress.setVisibility(View.VISIBLE);
|
||||||
homeBinding.swipeRefresh.setRefreshing(true);
|
homeBinding.swipeRefresh.setRefreshing(true);
|
||||||
updateProgress(lastResource, lastProgress, lastMaxProgress);
|
updateProgress(lastResource, lastProgress, lastMaxProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
homeBinding.noPackageManager.setVisibility(View.VISIBLE);
|
homeBinding.noPackageManager.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
@ -188,7 +203,25 @@ public class HomeFragment extends Fragment implements ComputeAppListTask.Listene
|
||||||
appListFragment.setApplications(apps);
|
appListFragment.setApplications(apps);
|
||||||
if (!apps.isEmpty()) {
|
if (!apps.isEmpty()) {
|
||||||
if (startupRefresh) {
|
if (startupRefresh) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(Utils.stringToDate(getContext(), last_refresh));
|
||||||
|
cal.add(Calendar.DAY_OF_YEAR, 1);
|
||||||
|
Date refreshAfter = cal.getTime();
|
||||||
|
Date currentDate = new Date();
|
||||||
|
if (last_refresh != null && !refreshInProgress && currentDate.after(refreshAfter)) {
|
||||||
|
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext());
|
||||||
|
dialogBuilder.setMessage(getString(R.string.refresh_needed_message, last_refresh));
|
||||||
|
dialogBuilder.setPositiveButton(R.string.refresh, (dialog, id) -> {
|
||||||
startRefresh();
|
startRefresh();
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
|
||||||
|
AlertDialog alertDialog = dialogBuilder.create();
|
||||||
|
alertDialog.show();
|
||||||
|
|
||||||
|
} else if (last_refresh == null) {
|
||||||
|
startRefresh();
|
||||||
|
}
|
||||||
startupRefresh = false;
|
startupRefresh = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,13 @@
|
||||||
package org.eu.exodus_privacy.exodusprivacy.manager;
|
package org.eu.exodus_privacy.exodusprivacy.manager;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import org.eu.exodus_privacy.exodusprivacy.R;
|
import org.eu.exodus_privacy.exodusprivacy.R;
|
||||||
|
import org.eu.exodus_privacy.exodusprivacy.Utils;
|
||||||
import org.eu.exodus_privacy.exodusprivacy.listener.NetworkListener;
|
import org.eu.exodus_privacy.exodusprivacy.listener.NetworkListener;
|
||||||
import org.eu.exodus_privacy.exodusprivacy.objects.Application;
|
import org.eu.exodus_privacy.exodusprivacy.objects.Application;
|
||||||
import org.eu.exodus_privacy.exodusprivacy.objects.Report;
|
import org.eu.exodus_privacy.exodusprivacy.objects.Report;
|
||||||
|
@ -54,6 +56,8 @@ import java.util.Random;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Singleton that handle all network connection
|
Singleton that handle all network connection
|
||||||
*/
|
*/
|
||||||
|
@ -113,15 +117,20 @@ public class NetworkManager {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
|
Message mes = null;
|
||||||
while (isRunning) {
|
while (isRunning) {
|
||||||
try {
|
try {
|
||||||
sem.acquire();
|
sem.acquire();
|
||||||
Message mes = messageQueue.remove(0);
|
mes = messageQueue.remove(0);
|
||||||
//noinspection SwitchStatementWithTooFewBranches
|
//noinspection SwitchStatementWithTooFewBranches
|
||||||
switch (mes.type) {
|
switch (mes.type) {
|
||||||
case GET_REPORTS:
|
case GET_REPORTS:
|
||||||
getTrackers(mes);
|
getTrackers(mes);
|
||||||
getApplications(mes);
|
getApplications(mes);
|
||||||
|
SharedPreferences sharedPreferences = mes.context.getSharedPreferences(Utils.APP_PREFS, MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||||
|
editor.putString(Utils.LAST_REFRESH, Utils.dateToString(new Date()));
|
||||||
|
editor.apply();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -45,7 +45,10 @@
|
||||||
<string name="tracker_presence_in">Present in:</string>
|
<string name="tracker_presence_in">Present in:</string>
|
||||||
<string name="no_app_found_tracker">This tracker seems not be present in your applications</string>
|
<string name="no_app_found_tracker">This tracker seems not be present in your applications</string>
|
||||||
<string name="source">Source: %s</string>
|
<string name="source">Source: %s</string>
|
||||||
|
<string name="refresh">Refresh</string>
|
||||||
|
<string name="cancel">Cancel</string>
|
||||||
|
<string name="refresh_needed">Refresh needed</string>
|
||||||
|
<string name="refresh_needed_message">Data have not been update since %1$s.\n\nWould you like to refresh them?</string>
|
||||||
<!-- Menu -->
|
<!-- Menu -->
|
||||||
<string name="menu_action_filter">Filter</string>
|
<string name="menu_action_filter">Filter</string>
|
||||||
<string name="menu_action_settings">Application Settings</string>
|
<string name="menu_action_settings">Application Settings</string>
|
||||||
|
|
Loading…
Reference in New Issue