Make the app smaller

Signed-off-by: Tad <tad@spotco.us>
This commit is contained in:
Tad 2023-02-07 10:22:36 -05:00
parent 1ab21d949a
commit 1fcaab82b8
No known key found for this signature in database
GPG key ID: B286E9F57A07424B
13 changed files with 89 additions and 107 deletions

View file

@ -6,8 +6,8 @@ android {
applicationId "us.spotco.malwarescanner" applicationId "us.spotco.malwarescanner"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 32 targetSdkVersion 32
versionCode 93 versionCode 94
versionName "2.28" versionName "2.29"
resConfigs 'en', 'af', 'de', 'es', 'fi', 'fr', 'it', 'pl', 'pt', 'ru' resConfigs 'en', 'af', 'de', 'es', 'fi', 'fr', 'it', 'pl', 'pt', 'ru'
} }
buildTypes { buildTypes {
@ -29,6 +29,5 @@ android {
} }
dependencies { dependencies {
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.8.0'
} }

View file

@ -18,14 +18,13 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@android:style/Theme.DeviceDefault"
android:largeHeap="true" android:largeHeap="true"
android:requestLegacyExternalStorage="true"> android:requestLegacyExternalStorage="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden" android:configChanges="orientation|keyboardHidden"
android:exported="true"> android:exported="true">

View file

@ -20,6 +20,7 @@ package us.spotco.malwarescanner;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import android.Manifest; import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
@ -28,7 +29,6 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@ -43,23 +43,16 @@ import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.File; import java.io.File;
import java.util.HashSet; import java.util.HashSet;
public class MainActivity extends AppCompatActivity { public class MainActivity extends Activity {
private SharedPreferences prefs = null; private SharedPreferences prefs = null;
private MalwareScanner malwareScanner = null; private MalwareScanner malwareScanner = null;
private TextView logView; private TextView logView;
private Menu menu;
private static final String buildVersionName = BuildConfig.VERSION_NAME; private static final String buildVersionName = BuildConfig.VERSION_NAME;
@ -72,12 +65,15 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
protected final void onCreate(Bundle savedInstanceState) { protected final void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
setTheme(android.R.style.Theme_DeviceDefault_DayNight);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Utils.setContext(getApplicationContext()); Utils.setContext(getApplicationContext());
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); setContentView(R.layout.content_main);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
@ -94,17 +90,6 @@ public class MainActivity extends AppCompatActivity {
prefs = getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE); prefs = getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
final FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(view -> {
if (!malwareScanner.running) {
startScanner();
} else {
logView.append("\n" + getString(R.string.main_cancelling_scan) + "\n\n");
malwareScanner.cancel(true);
malwareScanner.running = false;
}
});
requestPermissions(); requestPermissions();
Utils.considerStartService(this); Utils.considerStartService(this);
@ -113,23 +98,27 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public final boolean onCreateOptionsMenu(Menu menu) { public final boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu); getMenuInflater().inflate(R.menu.menu_main, menu);
this.menu = menu;
menu.findItem(R.id.toggleRealtime).setChecked(Utils.isServiceRunning(MalwareScannerService.class, this)); menu.findItem(R.id.toggleRealtime).setChecked(Utils.isServiceRunning(MalwareScannerService.class, this));
menu.findItem(R.id.toggleOnionRouting).setChecked(prefs.getBoolean("ONION_ROUTING", false)); menu.findItem(R.id.toggleOnionRouting).setChecked(prefs.getBoolean("ONION_ROUTING", false));
updateScanButton(false);
return true; return true;
} }
private void requestPermissions() { private void requestPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION_EXTERNAL_STORAGE); if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION_EXTERNAL_STORAGE);
}
}
if (SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
} }
if (SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
}
} }
private void showCredits() { private void showCredits() {
@ -272,6 +261,15 @@ public class MainActivity extends AppCompatActivity {
case R.id.mnuFullCredits: case R.id.mnuFullCredits:
showCredits(); showCredits();
break; break;
case R.id.btnStartScan:
if (!malwareScanner.running) {
updateScanButton(true);
startScanner();
} else {
logView.append("\n" + getString(R.string.main_cancelling_scan) + "\n\n");
malwareScanner.cancel(true);
malwareScanner.running = false;
}
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -294,7 +292,19 @@ public class MainActivity extends AppCompatActivity {
if (scanExternal) { if (scanExternal) {
filesToScan.add(new File("/storage")); filesToScan.add(new File("/storage"));
} }
malwareScanner.executeOnExecutor(Utils.getThreadPoolExecutor(), filesToScan); malwareScanner.executeOnExecutor(Utils.getThreadPoolExecutor(), filesToScan);
new Thread(() -> {
try {
while(malwareScanner.running){
Thread.sleep(500);
}
runOnUiThread(() -> updateScanButton(false));
} catch (Exception e) {
e.printStackTrace();
}
}).start();
} }
private void updateDatabase() { private void updateDatabase() {
@ -305,4 +315,26 @@ public class MainActivity extends AppCompatActivity {
} }
} }
private void updateScanButton(boolean running) {
if (running) {
if (SDK_INT >= Build.VERSION_CODES.O) {
menu.findItem(R.id.btnStartScan).setIconTintList(getColorStateList(R.color.colorRed));
} else {
findViewById(R.id.btnStartScan).setBackgroundColor(getResources().getColor(R.color.colorRed));
}
if (SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
menu.findItem(R.id.btnStartScan).setIcon(getDrawable(android.R.drawable.ic_menu_close_clear_cancel));
}
} else {
if (SDK_INT >= Build.VERSION_CODES.O) {
menu.findItem(R.id.btnStartScan).setIconTintList(getColorStateList(R.color.colorGreen));
} else {
findViewById(R.id.btnStartScan).setBackgroundColor(getResources().getColor(R.color.colorGreen));
}
if (SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
menu.findItem(R.id.btnStartScan).setIcon(getDrawable(android.R.drawable.ic_media_play));
}
}
}
} }

View file

@ -28,8 +28,6 @@ import android.os.Environment;
import android.os.SystemClock; import android.os.SystemClock;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.app.NotificationCompat;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
@ -78,15 +76,15 @@ class MalwareScanner extends AsyncTask<HashSet<File>, Object, String> {
} }
} else if (!userFacingOnly) { } else if (!userFacingOnly) {
String[] malwareDetect = result.split(" in "); String[] malwareDetect = result.split(" in ");
NotificationCompat.Builder mBuilder = Notification.Builder mBuilder =
new NotificationCompat.Builder(context) new Notification.Builder(context)
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setContentTitle(context.getText(R.string.lblNotificationRealtimeDetection) + " " + malwareDetect[0]) .setContentTitle(context.getText(R.string.lblNotificationRealtimeDetection) + " " + malwareDetect[0])
.setContentText(malwareDetect[1]) .setContentText(malwareDetect[1])
.setPriority(Notification.PRIORITY_MAX) .setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_VIBRATE); .setDefaults(Notification.DEFAULT_VIBRATE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setVisibility(NotificationCompat.VISIBILITY_SECRET); mBuilder.setVisibility(Notification.VISIBILITY_SECRET);
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mBuilder.setChannelId("DETECTION"); mBuilder.setChannelId("DETECTION");

View file

@ -29,8 +29,6 @@ import android.os.FileObserver;
import android.os.IBinder; import android.os.IBinder;
import android.widget.Toast; import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import java.io.File; import java.io.File;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.HashSet; import java.util.HashSet;
@ -40,7 +38,7 @@ public class MalwareScannerService extends Service {
private final HashSet<RecursiveFileObserver> malwareMonitors = new HashSet<>(); private final HashSet<RecursiveFileObserver> malwareMonitors = new HashSet<>();
private ThreadPoolExecutor threadPoolExecutor = null; private ThreadPoolExecutor threadPoolExecutor = null;
private NotificationCompat.Builder foregroundNotification = null; private Notification.Builder foregroundNotification = null;
private NotificationManager notificationManager = null; private NotificationManager notificationManager = null;
@Override @Override
@ -105,7 +103,7 @@ public class MalwareScannerService extends Service {
private void setForeground() { private void setForeground() {
foregroundNotification = foregroundNotification =
new NotificationCompat.Builder(this) new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setContentTitle(getText(R.string.lblNotificationRealtimeTitle)) .setContentTitle(getText(R.string.lblNotificationRealtimeTitle))
.setContentText(getText(R.string.lblNotificationRealtimeText)) .setContentText(getText(R.string.lblNotificationRealtimeText))

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="us.spotco.malwarescanner.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_media_play" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -2,6 +2,11 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context="us.spotco.malwarescanner.MainActivity"> tools:context="us.spotco.malwarescanner.MainActivity">
<item
android:id="@+id/btnStartScan"
android:title="@string/scan_control"
android:icon="@android:drawable/ic_media_play"
android:showAsAction="always"/>
<item <item
android:id="@+id/toggleOnionRouting" android:id="@+id/toggleOnionRouting"
android:title="@string/lblOnionRoutingToggle" android:title="@string/lblOnionRoutingToggle"

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="colorPrimary">#4CAF50</color> <color name="colorRed">#FF0000</color>
<color name="light_blue">#03a9f4</color> <color name="colorGreen">#008000</color>
<color name="red">#f44336</color> </resources>
</resources>

View file

@ -59,4 +59,5 @@
<string name="db_desc_size_small">Small</string> <string name="db_desc_size_small">Small</string>
<string name="db_desc_size_medium">Medium</string> <string name="db_desc_size_medium">Medium</string>
<string name="db_desc_size_large">Large</string> <string name="db_desc_size_large">Large</string>
<string name="scan_control">Scan Control</string>
</resources> </resources>

View file

@ -1,20 +0,0 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="colorAccent">@color/light_blue</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.DayNight" />
</resources>

View file

@ -0,0 +1 @@
* Don't trim hashes as much to reduce false positives

View file

@ -0,0 +1 @@
* Don't trim hashes as much to reduce false positives

View file

@ -0,0 +1,2 @@
* Make the app smalller
* Colorize the manual scan button when possible