Compare commits

..

No commits in common. "e784d515dc3df01b755e6832ce40e89ff68da19b" and "59cd02f91653aaeed8f474fd7aeedb7c6d997f92" have entirely different histories.

5 changed files with 75 additions and 93 deletions

View File

@ -1,5 +1,4 @@
.gradle .gradle
.idea/deploymentTargetSelector.xml
app/.externalNativeBuild app/.externalNativeBuild
app/build app/build
app/release app/release

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-03-07T07:26:40.093624067Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=RF8Y80CE2DA" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
<SelectionState runConfigName="New Run Config">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-03-06T00:03:16.988860344Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=a026a310" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
</project>

View File

@ -77,5 +77,4 @@ android {
dependencies { dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.biometric:biometric:1.1.0' implementation 'androidx.biometric:biometric:1.1.0'
implementation 'com.google.android.material:material:1.11.0'
} }

View File

@ -49,7 +49,6 @@ import androidx.annotation.NonNull;
import androidx.biometric.BiometricManager; import androidx.biometric.BiometricManager;
import androidx.biometric.BiometricPrompt; import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.google.android.material.snackbar.Snackbar;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -100,7 +99,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private ActivityResultLauncher<Intent> vpnPermissionLauncher; private ActivityResultLauncher<Intent> vpnPermissionLauncher;
private ActivityResultLauncher<String[]> requestPermissionsLauncher; private ActivityResultLauncher<String[]> requestPermissionsLauncher;
private ActivityResultLauncher<Intent> batteryOptLauncher;
private boolean isReadingLogs = false; private boolean isReadingLogs = false;
private final Handler sizeUpdateHandler = new Handler(); private final Handler sizeUpdateHandler = new Handler();
@ -135,14 +133,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
} }
); );
batteryOptLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
Log.d(TAG, "Regresamos de la pantalla de ajustes de batería");
checkBatteryOptimizations();
}
);
requestPermissionsLauncher = registerForActivityResult( requestPermissionsLauncher = registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultContracts.RequestMultiplePermissions(),
result -> { result -> {
@ -231,13 +221,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}; };
} }
private void showBatterySnackbar() {
View rootView = findViewById(android.R.id.content);
Snackbar.make(rootView, R.string.battery_opt_denied, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.fix_action, v -> checkBatteryOptimizations())
.show();
}
private void initiatePermissionChain() { private void initiatePermissionChain() {
List<String> permissions = new ArrayList<>(); List<String> permissions = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
@ -373,16 +356,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
// Comprobamos batería siempre que volvemos a la app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) {
// Si no está ignorado, mostramos el aviso (o Snackbar si ya se lanzó el diálogo)
Log.d(TAG, "onResume: Batería aún optimizada, mostrando aviso");
showBatterySnackbar();
}
}
if (getIntent() != null && getIntent().getBooleanExtra(VpnRecoveryReceiver.EXTRA_RECOVERY, false)) { if (getIntent() != null && getIntent().getBooleanExtra(VpnRecoveryReceiver.EXTRA_RECOVERY, false)) {
addToLog(getString(R.string.recovery_pulse_received)); addToLog(getString(R.string.recovery_pulse_received));
Intent vpnIntent = new Intent(this, TProxyService.class); Intent vpnIntent = new Intent(this, TProxyService.class);
@ -404,71 +377,55 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) { if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) {
String manufacturer = Build.MANUFACTURER.toLowerCase(); String manufacturer = Build.MANUFACTURER.toLowerCase();
String message = getString(R.string.battery_opt_msg); String message = getString(R.string.battery_opt_msg);
if (manufacturer.contains("oppo") || manufacturer.contains("realme")) {
message += getString(R.string.battery_opt_oppo_extra);
} else if (manufacturer.contains("xiaomi")) {
message += getString(R.string.battery_opt_xiaomi_extra);
}
if (manufacturer.contains("oppo") || manufacturer.contains("realme") || manufacturer.contains("xiaomi")) { new AlertDialog.Builder(this)
.setTitle(R.string.battery_opt_title)
if (manufacturer.contains("oppo") || manufacturer.contains("realme")) { .setMessage(message)
message += getString(R.string.battery_opt_oppo_extra); .setPositiveButton(R.string.go_to_settings, (dialog, which) -> openBatterySettings(manufacturer))
} else if (manufacturer.contains("xiaomi")) { .setNegativeButton(R.string.cancel, null)
message += getString(R.string.battery_opt_xiaomi_extra); .show();
} }
new AlertDialog.Builder(this)
.setTitle(R.string.battery_opt_title)
.setMessage(message)
.setPositiveButton(R.string.go_to_settings, (dialog, which) -> openBatterySettings(manufacturer))
.setNegativeButton(R.string.cancel, null)
.show();
}
else {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
batteryOptLauncher.launch(intent);
}
}
} }
} }
private void openBatterySettings(String manufacturer) { private void openBatterySettings(String manufacturer) {
boolean success = false; if (manufacturer.contains("oppo") || manufacturer.contains("realme")) {
try {
if (manufacturer.contains("oppo") || manufacturer.contains("realme")) { Intent intent = new Intent();
try { intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"));
Intent intent = new Intent(); startActivity(intent);
intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")); return;
startActivity(intent); } catch (Exception e) {
success = true; try {
} catch (Exception e) { Intent intent = new Intent();
try { intent.setComponent(new ComponentName("com.coloros.oppoguardelf", "com.coloros.oppoguardelf.Permission.BackgroundAllowAppListActivity"));
Intent intent = new Intent(); startActivity(intent);
intent.setComponent(new ComponentName("com.coloros.oppoguardelf", "com.coloros.oppoguardelf.Permission.BackgroundAllowAppListActivity")); return;
startActivity(intent); } catch (Exception e2) {}
success = true; }
} catch (Exception e2) {} } else if (manufacturer.contains("xiaomi")) {
} try {
} Intent intent = new Intent("miui.intent.action.APP_BATTERY_SAVER_SETTINGS");
else if (manufacturer.contains("xiaomi")) { intent.setComponent(new ComponentName("com.miui.powerkeeper", "com.miui.powerkeeper.ui.HiddenAppsConfigActivity"));
try { intent.putExtra("package_name", getPackageName());
Intent intent = new Intent("miui.intent.action.APP_BATTERY_SAVER_SETTINGS"); intent.putExtra("package_label", getString(R.string.app_name));
intent.setComponent(new ComponentName("com.miui.powerkeeper", "com.miui.powerkeeper.ui.HiddenAppsConfigActivity")); startActivity(intent);
intent.putExtra("package_name", getPackageName()); return;
intent.putExtra("package_label", getString(R.string.app_name)); } catch (Exception e) {}
startActivity(intent); }
success = true;
} catch (Exception e) {} Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
} intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
if (!success) { }
try {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
} catch (Exception ex) {
}
}
}
private void toggleTheme() { private void toggleTheme() {
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE); SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);

View File

@ -79,7 +79,5 @@
<!-- Brand specific battery warnings --> <!-- Brand specific battery warnings -->
<string name="battery_opt_oppo_extra">\n\nOPPO/Realme detected: Please ensure you also enable \'Allow background activity\' in this app\'s settings.</string> <string name="battery_opt_oppo_extra">\n\nOPPO/Realme detected: Please ensure you also enable \'Allow background activity\' in this app\'s settings.</string>
<string name="battery_opt_xiaomi_extra">\n\nXiaomi detected: Please set battery saver to \'No restrictions\' in settings.</string> <string name="battery_opt_xiaomi_extra">\n\nXiaomi detected: Please set battery saver to \'No restrictions\' for this app.</string>
<string name="battery_opt_denied">Para que la app funcione al 100%, desactiva la optimización de batería.</string>
<string name="fix_action">SOLUCIONAR</string>
</resources> </resources>