diff --git a/app/build.gradle b/app/build.gradle index 0d88d70e56..4dfd1e74d6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,7 +23,7 @@ android { defaultConfig { applicationId "eu.faircode.email" minSdkVersion 21 - targetSdkVersion 33 + targetSdkVersion 32 versionCode getVersionCode() versionName "1." + getVersionCode() archivesBaseName = "FairEmail-v$versionName" + getRevision() diff --git a/app/src/main/java/eu/faircode/email/ActivityAMP.java b/app/src/main/java/eu/faircode/email/ActivityAMP.java index 9f224587bf..c53e4582d3 100644 --- a/app/src/main/java/eu/faircode/email/ActivityAMP.java +++ b/app/src/main/java/eu/faircode/email/ActivityAMP.java @@ -165,7 +165,8 @@ public class ActivityAMP extends ActivityBase { private void setDarkMode() { WebSettings settings = wvAmp.getSettings(); boolean dark = (Helper.isDarkTheme(this) && !force_light); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || + Helper.getTargetSdk(this) < Build.VERSION_CODES.TIRAMISU) { if (WebViewEx.isFeatureSupported(WebViewFeature.FORCE_DARK)) WebSettingsCompat.setForceDark(settings, dark ? FORCE_DARK_ON : FORCE_DARK_OFF); } else diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogOpenFull.java b/app/src/main/java/eu/faircode/email/FragmentDialogOpenFull.java index 880434f0eb..ca80df3665 100644 --- a/app/src/main/java/eu/faircode/email/FragmentDialogOpenFull.java +++ b/app/src/main/java/eu/faircode/email/FragmentDialogOpenFull.java @@ -86,7 +86,8 @@ public class FragmentDialogOpenFull extends FragmentDialogBase { WebSettingsCompat.setSafeBrowsingEnabled(settings, safe_browsing); boolean dark = (Helper.isDarkTheme(context) && !force_light); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || + Helper.getTargetSdk(context) < Build.VERSION_CODES.TIRAMISU) { if (WebViewEx.isFeatureSupported(WebViewFeature.FORCE_DARK)) WebSettingsCompat.setForceDark(settings, dark ? FORCE_DARK_ON : FORCE_DARK_OFF); } else diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogPermissions.java b/app/src/main/java/eu/faircode/email/FragmentDialogPermissions.java index ddbfc95f74..470a07a1f4 100644 --- a/app/src/main/java/eu/faircode/email/FragmentDialogPermissions.java +++ b/app/src/main/java/eu/faircode/email/FragmentDialogPermissions.java @@ -74,7 +74,7 @@ public class FragmentDialogPermissions extends FragmentDialogBase { boolean hasContactPermissions = Helper.hasPermission(context, Manifest.permission.READ_CONTACTS); boolean hasNotificationPermissions = - (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || + (Helper.getTargetSdk(context) < Build.VERSION_CODES.TIRAMISU || Helper.hasPermission(context, Manifest.permission.POST_NOTIFICATIONS)); boolean isIgnoring = !Boolean.FALSE.equals(Helper.isIgnoringOptimizations(context)); boolean canScheduleExact = AlarmManagerCompatEx.canScheduleExactAlarms(getContext()); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 7ec532cbc0..bfae8aa500 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -623,9 +623,15 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. tvNotifications.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - v.getContext().startActivity( - new Intent(v.getContext(), ActivitySetup.class) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)); + Intent intent; + if (Helper.getTargetSdk(v.getContext()) < Build.VERSION_CODES.TIRAMISU) + intent = new Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.parse("package:" + BuildConfig.APPLICATION_ID)); + else + intent = new Intent(v.getContext(), ActivitySetup.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + v.getContext().startActivity(intent); } }); @@ -4476,20 +4482,21 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. iff.addAction(ACTION_KEYWORDS); lbm.registerReceiver(receiver, iff); - ConnectivityManager cm = Helper.getSystemService(getContext(), ConnectivityManager.class); + final Context context = getContext(); + ConnectivityManager cm = Helper.getSystemService(context, ConnectivityManager.class); NetworkRequest.Builder builder = new NetworkRequest.Builder(); builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); cm.registerNetworkCallback(builder.build(), networkCallback); - updateAirplaneMode(ConnectionHelper.airplaneMode(getContext())); - getContext().registerReceiver(airplanemode, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); + updateAirplaneMode(ConnectionHelper.airplaneMode(context)); + context.registerReceiver(airplanemode, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); boolean canNotify = (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || hasPermission(Manifest.permission.POST_NOTIFICATIONS)); grpNotifications.setVisibility(canNotify ? View.GONE : View.VISIBLE); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean compact = prefs.getBoolean("compact", false); int zoom = prefs.getInt("view_zoom", compact ? 0 : 1); adapter.setCompact(compact); @@ -4546,15 +4553,16 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. public void onPause() { super.onPause(); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + final Context context = getContext(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); prefs.unregisterOnSharedPreferenceChangeListener(this); - getContext().unregisterReceiver(airplanemode); + context.unregisterReceiver(airplanemode); - ConnectivityManager cm = Helper.getSystemService(getContext(), ConnectivityManager.class); + ConnectivityManager cm = Helper.getSystemService(context, ConnectivityManager.class); cm.unregisterNetworkCallback(networkCallback); - LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); lbm.unregisterReceiver(receiver); } diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java index c2b4916486..27cabf108e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptions.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java @@ -484,15 +484,16 @@ public class FragmentOptions extends FragmentBase { } private void onExit() { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + final Context context = getContext(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean setup_reminder = prefs.getBoolean("setup_reminder", true); boolean hasContactPermissions = hasPermission(Manifest.permission.READ_CONTACTS); boolean hasNotificationPermissions = - (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || + (Helper.getTargetSdk(context) < Build.VERSION_CODES.TIRAMISU || hasPermission(Manifest.permission.POST_NOTIFICATIONS)); - boolean isIgnoring = !Boolean.FALSE.equals(Helper.isIgnoringOptimizations(getContext())); + boolean isIgnoring = !Boolean.FALSE.equals(Helper.isIgnoringOptimizations(context)); if (!setup_reminder || (hasContactPermissions && hasNotificationPermissions && isIgnoring)) diff --git a/app/src/main/java/eu/faircode/email/FragmentSetup.java b/app/src/main/java/eu/faircode/email/FragmentSetup.java index a5cc00591f..2119972254 100644 --- a/app/src/main/java/eu/faircode/email/FragmentSetup.java +++ b/app/src/main/java/eu/faircode/email/FragmentSetup.java @@ -470,13 +470,14 @@ public class FragmentSetup extends FragmentBase { btnPermissions.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View view) { + public void onClick(View v) { try { btnPermissions.setEnabled(false); List requesting = new ArrayList<>(); - for (String permission : getDesiredPermissions()) + for (String permission : Helper.getDesiredPermissions(getContext())) if (!hasPermission(permission)) requesting.add((permission)); + Log.i("Requesting permissions " + TextUtils.join(",", requesting)); requestPermissions(requesting.toArray(new String[0]), REQUEST_PERMISSIONS); } catch (Throwable ex) { Log.unexpectedError(getParentFragmentManager(), ex); @@ -978,6 +979,9 @@ public class FragmentSetup extends FragmentBase { for (int i = 0; i < Math.min(permissions.length, grantResults.length); i++) { String key = "requested." + permissions[i]; + Log.i("Permission " + permissions[i] + "=" + + (grantResults[i] == PackageManager.PERMISSION_GRANTED)); + if (grantResults[i] == PackageManager.PERMISSION_DENIED && grantResults[i] == prefs.getInt(key, PackageManager.PERMISSION_GRANTED)) denied++; @@ -999,17 +1003,9 @@ public class FragmentSetup extends FragmentBase { } } - private List getDesiredPermissions() { - List permissions = new ArrayList<>(); - permissions.add(Manifest.permission.READ_CONTACTS); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) - permissions.add(Manifest.permission.POST_NOTIFICATIONS); - return permissions; - } - private void setGrantedPermissions() { boolean all = true; - for (String permission : getDesiredPermissions()) + for (String permission : Helper.getDesiredPermissions(getContext())) if (!hasPermission(permission)) { all = false; break; diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index 6a28a9800b..8c40fb2bd8 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -38,6 +38,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -162,6 +163,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.regex.Pattern; public class Helper { + private static Integer targetSdk = null; private static Boolean hasWebView = null; private static Boolean hasPlayStore = null; private static Boolean hasValidFingerprint = null; @@ -389,6 +391,14 @@ public class Helper { return true; } + static String[] getDesiredPermissions(Context context) { + List permissions = new ArrayList<>(); + permissions.add(Manifest.permission.READ_CONTACTS); + if (getTargetSdk(context) >= Build.VERSION_CODES.TIRAMISU) + permissions.add(Manifest.permission.POST_NOTIFICATIONS); + return permissions.toArray(new String[0]); + } + static String[] getOAuthPermissions() { List permissions = new ArrayList<>(); //permissions.add(Manifest.permission.READ_CONTACTS); // profile @@ -997,6 +1007,19 @@ public class Helper { return 0; } + static int getTargetSdk(Context context) { + if (targetSdk == null) + try { + PackageManager pm = context.getPackageManager(); + ApplicationInfo ai = pm.getApplicationInfo(BuildConfig.APPLICATION_ID, 0); + targetSdk = ai.targetSdkVersion; + } catch (Throwable ex) { + Log.e(ex); + targetSdk = Build.VERSION.SDK_INT; + } + return targetSdk; + } + static boolean isSupportedDevice() { if ("Amazon".equals(Build.BRAND) && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { /* diff --git a/app/src/main/java/eu/faircode/email/Log.java b/app/src/main/java/eu/faircode/email/Log.java index db37f74d02..aead994ff0 100644 --- a/app/src/main/java/eu/faircode/email/Log.java +++ b/app/src/main/java/eu/faircode/email/Log.java @@ -32,7 +32,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PermissionGroupInfo; @@ -1813,14 +1812,6 @@ public class Log { PackageManager pm = context.getPackageManager(); String installer = pm.getInstallerPackageName(BuildConfig.APPLICATION_ID); - int targetSdk = -1; - try { - ApplicationInfo ai = pm.getApplicationInfo(BuildConfig.APPLICATION_ID, 0); - targetSdk = ai.targetSdkVersion; - } catch (PackageManager.NameNotFoundException ex) { - sb.append(ex).append("\r\n"); - } - // Get version info sb.append(String.format("%s %s/%d%s%s%s%s\r\n", context.getString(R.string.app_name), @@ -1831,8 +1822,8 @@ public class Log { BuildConfig.DEBUG ? "d" : "", ActivityBilling.isPro(context) ? "+" : "-")); sb.append(String.format("Package: %s\r\n", BuildConfig.APPLICATION_ID)); - sb.append(String.format("Android: %s (SDK %d/%d)\r\n", - Build.VERSION.RELEASE, Build.VERSION.SDK_INT, targetSdk)); + sb.append(String.format("Android: %s (SDK device=%d target=%d)\r\n", + Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Helper.getTargetSdk(context))); boolean reporting = prefs.getBoolean("crash_reports", false); if (reporting || BuildConfig.TEST_RELEASE) { diff --git a/app/src/main/java/eu/faircode/email/WebViewEx.java b/app/src/main/java/eu/faircode/email/WebViewEx.java index 4ea5cf300d..02204ce895 100644 --- a/app/src/main/java/eu/faircode/email/WebViewEx.java +++ b/app/src/main/java/eu/faircode/email/WebViewEx.java @@ -118,7 +118,8 @@ public class WebViewEx extends WebView implements DownloadListener, View.OnLongC WebSettings settings = getSettings(); boolean dark = Helper.isDarkTheme(context); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || + Helper.getTargetSdk(context) < Build.VERSION_CODES.TIRAMISU) { boolean canForce = WebViewEx.isFeatureSupported(WebViewFeature.FORCE_DARK); if (canForce) WebSettingsCompat.setForceDark(settings, dark && !force_light ? FORCE_DARK_ON : FORCE_DARK_OFF);