all go to app info for baterry settings
This commit is contained in:
parent
3c1b920d42
commit
177b025139
|
|
@ -4,10 +4,10 @@
|
|||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2026-03-07T04:28:01.557850134Z">
|
||||
<DropdownSelection timestamp="2026-03-07T07:26:40.093624067Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=a026a310" />
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=RF8Y80CE2DA" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
|
|
|
|||
|
|
@ -129,12 +129,10 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
if (result.getResultCode() == RESULT_OK && prefs.getEnable()) {
|
||||
connectVpn();
|
||||
}
|
||||
// Chain: Check battery after VPN dialog
|
||||
checkBatteryOptimizations();
|
||||
}
|
||||
);
|
||||
|
||||
// Modern ordered permission requester
|
||||
requestPermissionsLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.RequestMultiplePermissions(),
|
||||
result -> {
|
||||
|
|
@ -145,7 +143,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
addToLog(entry.getValue() ? "Notification permission granted" : "Notification permission denied");
|
||||
}
|
||||
}
|
||||
// Step 2: After system permissions, request VPN permission
|
||||
prepareVpn();
|
||||
}
|
||||
);
|
||||
|
|
@ -211,8 +208,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
applySavedTheme();
|
||||
setVersionFooter();
|
||||
updateUI();
|
||||
|
||||
// Start sequential permission chain
|
||||
initiatePermissionChain();
|
||||
|
||||
addToLog(getString(R.string.app_started));
|
||||
|
|
@ -394,9 +389,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.battery_opt_title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.go_to_settings, (dialog, which) -> {
|
||||
openBatterySettings(manufacturer);
|
||||
})
|
||||
.setPositiveButton(R.string.go_to_settings, (dialog, which) -> openBatterySettings(manufacturer))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
|
@ -407,34 +400,29 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
if (manufacturer.contains("oppo") || manufacturer.contains("realme")) {
|
||||
try {
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(new ComponentName("com.coloros.safecenter",
|
||||
"com.coloros.safecenter.permission.startup.StartupAppListActivity"));
|
||||
intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"));
|
||||
startActivity(intent);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(new ComponentName("com.coloros.oppoguardelf",
|
||||
"com.coloros.oppoguardelf.Permission.BackgroundAllowAppListActivity"));
|
||||
intent.setComponent(new ComponentName("com.coloros.oppoguardelf", "com.coloros.oppoguardelf.Permission.BackgroundAllowAppListActivity"));
|
||||
startActivity(intent);
|
||||
return;
|
||||
} catch (Exception e2) {
|
||||
}
|
||||
} catch (Exception e2) {}
|
||||
}
|
||||
} else if (manufacturer.contains("xiaomi")) {
|
||||
try {
|
||||
Intent intent = new Intent("miui.intent.action.APP_BATTERY_SAVER_SETTINGS");
|
||||
intent.setComponent(new ComponentName("com.miui.powerkeeper",
|
||||
"com.miui.powerkeeper.ui.HiddenAppsConfigActivity"));
|
||||
intent.setComponent(new ComponentName("com.miui.powerkeeper", "com.miui.powerkeeper.ui.HiddenAppsConfigActivity"));
|
||||
intent.putExtra("package_name", getPackageName());
|
||||
intent.putExtra("package_label", getString(R.string.app_name));
|
||||
startActivity(intent);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
||||
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
|
@ -442,20 +430,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
private void toggleTheme() {
|
||||
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
|
||||
int currentMode = AppCompatDelegate.getDefaultNightMode();
|
||||
int nextMode;
|
||||
|
||||
if (currentMode == AppCompatDelegate.MODE_NIGHT_NO) {
|
||||
nextMode = AppCompatDelegate.MODE_NIGHT_YES;
|
||||
} else if (currentMode == AppCompatDelegate.MODE_NIGHT_YES) {
|
||||
nextMode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||
} else {
|
||||
nextMode = AppCompatDelegate.MODE_NIGHT_NO;
|
||||
}
|
||||
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putInt("ui_mode", nextMode);
|
||||
editor.apply();
|
||||
|
||||
int nextMode = (currentMode == AppCompatDelegate.MODE_NIGHT_NO) ? AppCompatDelegate.MODE_NIGHT_YES :
|
||||
(currentMode == AppCompatDelegate.MODE_NIGHT_YES) ? AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM : AppCompatDelegate.MODE_NIGHT_NO;
|
||||
sharedPref.edit().putInt("ui_mode", nextMode).apply();
|
||||
AppCompatDelegate.setDefaultNightMode(nextMode);
|
||||
updateThemeToggleButton(nextMode);
|
||||
}
|
||||
|
|
@ -468,32 +445,22 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
}
|
||||
|
||||
private void updateThemeToggleButton(int mode) {
|
||||
if (mode == AppCompatDelegate.MODE_NIGHT_NO) {
|
||||
themeToggle.setImageResource(R.drawable.ic_theme_dark);
|
||||
} else if (mode == AppCompatDelegate.MODE_NIGHT_YES) {
|
||||
themeToggle.setImageResource(R.drawable.ic_theme_light);
|
||||
} else {
|
||||
themeToggle.setImageResource(R.drawable.ic_theme_system);
|
||||
}
|
||||
if (mode == AppCompatDelegate.MODE_NIGHT_NO) themeToggle.setImageResource(R.drawable.ic_theme_dark);
|
||||
else if (mode == AppCompatDelegate.MODE_NIGHT_YES) themeToggle.setImageResource(R.drawable.ic_theme_light);
|
||||
else themeToggle.setImageResource(R.drawable.ic_theme_system);
|
||||
}
|
||||
|
||||
private void toggleVisibility(View view, TextView label, String text) {
|
||||
if (view.getVisibility() == View.GONE) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
label.setText("▼ " + text);
|
||||
} else {
|
||||
view.setVisibility(View.GONE);
|
||||
label.setText("▶ " + text);
|
||||
}
|
||||
boolean isGone = view.getVisibility() == View.GONE;
|
||||
view.setVisibility(isGone ? View.VISIBLE : View.GONE);
|
||||
label.setText((isGone ? "▼ " : "▶ ") + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
IntentFilter filter = new IntentFilter(IIABWatchdog.ACTION_LOG_MESSAGE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
registerReceiver(logReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
registerReceiver(logReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
|
||||
} else {
|
||||
registerReceiver(logReceiver, filter);
|
||||
|
|
@ -503,11 +470,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
try {
|
||||
unregisterReceiver(logReceiver);
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
try { unregisterReceiver(logReceiver); } catch (Exception e) {}
|
||||
stopLogSizeUpdates();
|
||||
}
|
||||
|
||||
|
|
@ -522,13 +485,10 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
savePrefs();
|
||||
Toast.makeText(this, R.string.saved_toast, Toast.LENGTH_SHORT).show();
|
||||
addToLog(getString(R.string.settings_saved));
|
||||
} else if (view.getId() == R.id.control) {
|
||||
handleControlClick();
|
||||
} else if (view.getId() == R.id.watchdog_control) {
|
||||
handleWatchdogClick();
|
||||
} else if (view.getId() == R.id.btn_clear_log) {
|
||||
showResetLogConfirmation();
|
||||
} else if (view.getId() == R.id.btn_copy_log) {
|
||||
} else if (view.getId() == R.id.control) handleControlClick();
|
||||
else if (view.getId() == R.id.watchdog_control) handleWatchdogClick();
|
||||
else if (view.getId() == R.id.btn_clear_log) showResetLogConfirmation();
|
||||
else if (view.getId() == R.id.btn_copy_log) {
|
||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("IIAB Log", connectionLog.getText().toString());
|
||||
if (clipboard != null) {
|
||||
|
|
@ -543,8 +503,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
.setTitle(R.string.log_reset_confirm_title)
|
||||
.setMessage(R.string.log_reset_confirm_msg)
|
||||
.setPositiveButton(R.string.reset_log, (dialog, which) -> resetLogFile())
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
.setNegativeButton(R.string.cancel, null).show();
|
||||
}
|
||||
|
||||
private void resetLogFile() {
|
||||
|
|
@ -553,8 +512,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
pw.print("");
|
||||
connectionLog.setText("");
|
||||
addToLog(getString(R.string.log_reset_user));
|
||||
SharedPreferences internalPrefs = getSharedPreferences("IIAB_Internal", Context.MODE_PRIVATE);
|
||||
internalPrefs.edit().putBoolean(IIABWatchdog.PREF_RAPID_GROWTH, false).apply();
|
||||
getSharedPreferences("IIAB_Internal", Context.MODE_PRIVATE).edit().putBoolean(IIABWatchdog.PREF_RAPID_GROWTH, false).apply();
|
||||
if (logWarning != null) logWarning.setVisibility(View.GONE);
|
||||
updateLogSizeUI();
|
||||
Toast.makeText(this, R.string.log_cleared_toast, Toast.LENGTH_SHORT).show();
|
||||
|
|
@ -564,12 +522,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
}
|
||||
|
||||
private void handleWatchdogClick() {
|
||||
boolean isEnabled = prefs.getWatchdogEnable();
|
||||
if (isEnabled) {
|
||||
showWatchdogBiometricPrompt();
|
||||
} else {
|
||||
toggleWatchdog(false);
|
||||
}
|
||||
if (prefs.getWatchdogEnable()) showWatchdogBiometricPrompt();
|
||||
else toggleWatchdog(false);
|
||||
}
|
||||
|
||||
private void toggleWatchdog(boolean stop) {
|
||||
|
|
@ -579,35 +533,24 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
stopService(intent);
|
||||
addToLog(getString(R.string.watchdog_stopped));
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(intent.setAction(WatchdogService.ACTION_START));
|
||||
} else {
|
||||
startService(intent.setAction(WatchdogService.ACTION_START));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(intent.setAction(WatchdogService.ACTION_START));
|
||||
else startService(intent.setAction(WatchdogService.ACTION_START));
|
||||
addToLog(getString(R.string.watchdog_started));
|
||||
}
|
||||
updateUI();
|
||||
}
|
||||
|
||||
private void handleControlClick() {
|
||||
boolean isCurrentlyEnabled = prefs.getEnable();
|
||||
if (isCurrentlyEnabled) {
|
||||
showBiometricPrompt();
|
||||
} else {
|
||||
BiometricManager biometricManager = BiometricManager.from(this);
|
||||
int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||
authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
}
|
||||
boolean isSecure = false;
|
||||
if (prefs.getEnable()) showBiometricPrompt();
|
||||
else {
|
||||
BiometricManager bm = BiometricManager.from(this);
|
||||
int auth = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) auth = BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
android.app.KeyguardManager km = (android.app.KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
|
||||
if (km != null && km.isDeviceSecure()) isSecure = true;
|
||||
if (biometricManager.canAuthenticate(authenticators) == BiometricManager.BIOMETRIC_SUCCESS || isSecure) {
|
||||
if (bm.canAuthenticate(auth) == BiometricManager.BIOMETRIC_SUCCESS || (km != null && km.isDeviceSecure())) {
|
||||
addToLog(getString(R.string.user_initiated_conn));
|
||||
toggleService(false);
|
||||
} else {
|
||||
showEnrollmentDialog();
|
||||
}
|
||||
} else showEnrollmentDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -624,9 +567,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
}
|
||||
|
||||
private void showBiometricPrompt() {
|
||||
Executor executor = ContextCompat.getMainExecutor(this);
|
||||
BiometricPrompt biometricPrompt = new BiometricPrompt(MainActivity.this,
|
||||
executor, new BiometricPrompt.AuthenticationCallback() {
|
||||
Executor ex = ContextCompat.getMainExecutor(this);
|
||||
BiometricPrompt bp = new BiometricPrompt(this, ex, new BiometricPrompt.AuthenticationCallback() {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
|
|
@ -634,45 +576,30 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
toggleService(true);
|
||||
}
|
||||
});
|
||||
int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
|
||||
.setTitle(getString(R.string.auth_required_title))
|
||||
.setSubtitle(getString(R.string.auth_required_subtitle))
|
||||
.setAllowedAuthenticators(authenticators)
|
||||
.build();
|
||||
biometricPrompt.authenticate(promptInfo);
|
||||
int auth = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
bp.authenticate(new BiometricPrompt.PromptInfo.Builder().setTitle(getString(R.string.auth_required_title)).setSubtitle(getString(R.string.auth_required_subtitle)).setAllowedAuthenticators(auth).build());
|
||||
}
|
||||
|
||||
private void showWatchdogBiometricPrompt() {
|
||||
Executor executor = ContextCompat.getMainExecutor(this);
|
||||
BiometricPrompt biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
|
||||
Executor ex = ContextCompat.getMainExecutor(this);
|
||||
BiometricPrompt bp = new BiometricPrompt(this, ex, new BiometricPrompt.AuthenticationCallback() {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
toggleWatchdog(true);
|
||||
}
|
||||
});
|
||||
int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
|
||||
.setTitle(getString(R.string.unlock_watchdog_title))
|
||||
.setSubtitle(getString(R.string.unlock_watchdog_subtitle))
|
||||
.setAllowedAuthenticators(authenticators)
|
||||
.build();
|
||||
biometricPrompt.authenticate(promptInfo);
|
||||
int auth = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
bp.authenticate(new BiometricPrompt.PromptInfo.Builder().setTitle(getString(R.string.unlock_watchdog_title)).setSubtitle(getString(R.string.unlock_watchdog_subtitle)).setAllowedAuthenticators(auth).build());
|
||||
}
|
||||
|
||||
private void toggleService(boolean isEnable) {
|
||||
prefs.setEnable(!isEnable);
|
||||
private void toggleService(boolean stop) {
|
||||
prefs.setEnable(!stop);
|
||||
savePrefs();
|
||||
updateUI();
|
||||
Intent intent = new Intent(this, TProxyService.class);
|
||||
if (isEnable) {
|
||||
startService(intent.setAction(TProxyService.ACTION_DISCONNECT));
|
||||
addToLog(getString(R.string.vpn_stopping));
|
||||
} else {
|
||||
startService(intent.setAction(TProxyService.ACTION_CONNECT));
|
||||
addToLog(getString(R.string.vpn_starting));
|
||||
}
|
||||
startService(intent.setAction(stop ? TProxyService.ACTION_DISCONNECT : TProxyService.ACTION_CONNECT));
|
||||
addToLog(getString(stop ? R.string.vpn_stopping : R.string.vpn_starting));
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
|
|
@ -739,9 +666,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
|
||||
private void scrollToBottom() {
|
||||
if (connectionLog.getLayout() != null) {
|
||||
final int scrollAmount = connectionLog.getLayout().getLineTop(connectionLog.getLineCount()) - connectionLog.getHeight();
|
||||
if (scrollAmount > 0)
|
||||
connectionLog.scrollTo(0, scrollAmount);
|
||||
int scroll = connectionLog.getLayout().getLineTop(connectionLog.getLineCount()) - connectionLog.getHeight();
|
||||
if (scroll > 0) connectionLog.scrollTo(0, scroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue