[controller] mejorar tabla de permismos
This commit is contained in:
parent
d393748393
commit
a041c433f9
|
|
@ -636,11 +636,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
filter.addAction(WatchdogService.ACTION_STATE_STARTED);
|
||||
filter.addAction(WatchdogService.ACTION_STATE_STOPPED);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
registerReceiver(logReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
|
||||
} else {
|
||||
registerReceiver(logReceiver, filter);
|
||||
}
|
||||
ContextCompat.registerReceiver(this, logReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
|
@ -19,6 +22,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
|
|||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
public class SetupActivity extends AppCompatActivity {
|
||||
|
||||
|
|
@ -26,6 +30,9 @@ public class SetupActivity extends AppCompatActivity {
|
|||
|
||||
private SwitchCompat switchNotif, switchTermux, switchVpn, switchBattery;
|
||||
private Button btnContinue;
|
||||
private Button btnManageAll;
|
||||
private Button btnTermuxOverlay;
|
||||
private Button btnManageTermux;
|
||||
|
||||
private ActivityResultLauncher<String> requestPermissionLauncher;
|
||||
private ActivityResultLauncher<Intent> vpnLauncher;
|
||||
|
|
@ -44,6 +51,9 @@ public class SetupActivity extends AppCompatActivity {
|
|||
switchVpn = findViewById(R.id.switch_perm_vpn);
|
||||
switchBattery = findViewById(R.id.switch_perm_battery);
|
||||
btnContinue = findViewById(R.id.btn_setup_continue);
|
||||
btnManageAll = findViewById(R.id.btn_manage_all);
|
||||
btnTermuxOverlay = findViewById(R.id.btn_termux_overlay);
|
||||
btnManageTermux = findViewById(R.id.btn_manage_termux);
|
||||
|
||||
// Hide Notification switch if Android < 13
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
|
|
@ -82,22 +92,34 @@ public class SetupActivity extends AppCompatActivity {
|
|||
|
||||
private void setupListeners() {
|
||||
switchNotif.setOnClickListener(v -> {
|
||||
if (hasNotifPermission()) {
|
||||
handleRevokeAttempt(v);
|
||||
return;
|
||||
}
|
||||
if (switchNotif.isChecked()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
|
||||
}
|
||||
}
|
||||
switchNotif.setChecked(hasNotifPermission()); // Revert visual state pending system response
|
||||
switchNotif.setChecked(false); // Force visual state back until system confirms
|
||||
});
|
||||
|
||||
switchTermux.setOnClickListener(v -> {
|
||||
if (hasTermuxPermission()) {
|
||||
handleRevokeAttempt(v);
|
||||
return;
|
||||
}
|
||||
if (switchTermux.isChecked()) {
|
||||
requestPermissionLauncher.launch(TERMUX_PERMISSION);
|
||||
}
|
||||
switchTermux.setChecked(hasTermuxPermission());
|
||||
switchTermux.setChecked(false);
|
||||
});
|
||||
|
||||
switchVpn.setOnClickListener(v -> {
|
||||
if (hasVpnPermission()) {
|
||||
handleRevokeAttempt(v);
|
||||
return;
|
||||
}
|
||||
if (switchVpn.isChecked()) {
|
||||
Intent intent = VpnService.prepare(this);
|
||||
if (intent != null) {
|
||||
|
|
@ -106,10 +128,14 @@ public class SetupActivity extends AppCompatActivity {
|
|||
checkAllPermissions(); // Already granted
|
||||
}
|
||||
}
|
||||
switchVpn.setChecked(hasVpnPermission());
|
||||
switchVpn.setChecked(false);
|
||||
});
|
||||
|
||||
switchBattery.setOnClickListener(v -> {
|
||||
if (hasBatteryPermission()) {
|
||||
handleRevokeAttempt(v);
|
||||
return;
|
||||
}
|
||||
if (switchBattery.isChecked()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
||||
|
|
@ -117,7 +143,30 @@ public class SetupActivity extends AppCompatActivity {
|
|||
batteryLauncher.launch(intent);
|
||||
}
|
||||
}
|
||||
switchBattery.setChecked(hasBatteryPermission());
|
||||
switchBattery.setChecked(false);
|
||||
});
|
||||
// Direct access to all the Controller permissions
|
||||
btnManageAll.setOnClickListener(v -> openAppSettings());
|
||||
// Direct access to Termux Overlay permissions
|
||||
btnTermuxOverlay.setOnClickListener(v -> {
|
||||
try {
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
|
||||
intent.setData(Uri.parse("package:com.termux"));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(v, "Termux is not installed or device not supported.", Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
// Direct access to Controller settings (Reuses the method from Phase 1)
|
||||
btnManageTermux.setOnClickListener(v -> {
|
||||
try {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:com.termux"));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(v, "Termux is not installed.", Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -127,6 +176,29 @@ public class SetupActivity extends AppCompatActivity {
|
|||
checkAllPermissions(); // Refresh state if user returns from settings
|
||||
}
|
||||
|
||||
/**
|
||||
* It displays visual feedback (shake) and a message when the user
|
||||
* tries to turn off a permission.
|
||||
*/
|
||||
private void handleRevokeAttempt(View switchView) {
|
||||
// Force the switch to stay checked visually
|
||||
((SwitchCompat) switchView).setChecked(true);
|
||||
|
||||
// Animate the switch (Shake)
|
||||
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
|
||||
switchView.startAnimation(shake);
|
||||
|
||||
// Show Snackbar with action to go to Settings
|
||||
Snackbar.make(findViewById(android.R.id.content), "To revoke permissions, you must do it from system settings.", Snackbar.LENGTH_LONG)
|
||||
.setAction("SETTINGS", v -> openAppSettings()).show();
|
||||
}
|
||||
|
||||
private void openAppSettings() {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void checkAllPermissions() {
|
||||
boolean notif = hasNotifPermission();
|
||||
boolean termux = hasTermuxPermission();
|
||||
|
|
@ -138,12 +210,6 @@ public class SetupActivity extends AppCompatActivity {
|
|||
switchVpn.setChecked(vpn);
|
||||
switchBattery.setChecked(battery);
|
||||
|
||||
// Lock switches if already granted to prevent user confusion
|
||||
if (notif) switchNotif.setEnabled(false);
|
||||
if (termux) switchTermux.setEnabled(false);
|
||||
if (vpn) switchVpn.setEnabled(false);
|
||||
if (battery) switchBattery.setEnabled(false);
|
||||
|
||||
boolean allGranted = termux && vpn && battery;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
allGranted = allGranted && notif;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:fillAfter="true">
|
||||
|
||||
<translate
|
||||
android:startOffset="0"
|
||||
android:fromXDelta="0%p"
|
||||
android:toXDelta="5%p"
|
||||
android:duration="50" />
|
||||
|
||||
<translate
|
||||
android:startOffset="50"
|
||||
android:fromXDelta="5%p"
|
||||
android:toXDelta="-5%p"
|
||||
android:duration="50" />
|
||||
|
||||
<translate
|
||||
android:startOffset="100"
|
||||
android:fromXDelta="-5%p"
|
||||
android:toXDelta="5%p"
|
||||
android:duration="50" />
|
||||
|
||||
<translate
|
||||
android:startOffset="150"
|
||||
android:fromXDelta="5%p"
|
||||
android:toXDelta="-5%p"
|
||||
android:duration="50" />
|
||||
|
||||
<translate
|
||||
android:startOffset="200"
|
||||
android:fromXDelta="-5%p"
|
||||
android:toXDelta="0%p"
|
||||
android:duration="50" />
|
||||
</set>
|
||||
|
|
@ -38,7 +38,8 @@
|
|||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:paddingVertical="12dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
android:layout_marginBottom="8dp"
|
||||
android:theme="@style/PurpleSwitchTheme"/>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/switch_perm_termux"
|
||||
|
|
@ -48,7 +49,8 @@
|
|||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:paddingVertical="12dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
android:layout_marginBottom="8dp"
|
||||
android:theme="@style/PurpleSwitchTheme"/>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/switch_perm_vpn"
|
||||
|
|
@ -58,7 +60,8 @@
|
|||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:paddingVertical="12dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
android:layout_marginBottom="8dp"
|
||||
android:theme="@style/PurpleSwitchTheme"/>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/switch_perm_battery"
|
||||
|
|
@ -68,8 +71,60 @@
|
|||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:paddingVertical="12dp"
|
||||
android:theme="@style/PurpleSwitchTheme"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_manage_all"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Manage All Permissions"
|
||||
android:textAllCaps="false"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:minHeight="0dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:layout_marginBottom="12dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Termux custom permissions"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_termux_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Display over other apps"
|
||||
android:textAllCaps="false"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="@color/lightGray66" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_manage_termux"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Manage Termux permissions"
|
||||
android:textAllCaps="false"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="@color/lightGray66" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<color name="colorAccent">#2E7D32</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="black">#000000</color>
|
||||
|
||||
<color name="lightGray66">#AAAAAA</color>
|
||||
<color name="background_dark">#121212</color>
|
||||
|
||||
<!-- Status Colors (Fixed for readability) -->
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
<color name="btn_vpn_on_dim">#EF9A9A</color>
|
||||
<color name="btn_vpn_off_dim">#A5D6A7</color>
|
||||
|
||||
<!-- Secciones -->
|
||||
<!-- Sections -->
|
||||
<color name="section_header_bg">#333333</color>
|
||||
<color name="section_body_bg_light">#F5F5F5</color>
|
||||
<color name="section_body_bg_dark">#1A1A1A</color>
|
||||
|
|
|
|||
|
|
@ -17,4 +17,7 @@
|
|||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:backgroundDimEnabled">false</item>
|
||||
</style>
|
||||
<style name="PurpleSwitchTheme" parent="">
|
||||
<item name="colorControlActivated">#8A2BE2</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in New Issue