From d0503942bcded27bbb3c04845a638df7fecb860c Mon Sep 17 00:00:00 2001 From: Raymond Lai Date: Sat, 18 Feb 2023 11:40:45 +0800 Subject: [PATCH 1/6] SDK 33 adaptations + lib upgrades It has to happen anyway. - Compile with SDK 33 - Use Kotlin 1.8 - Use Java 11 - Library upgrades - Fix syntax and API problems brought by the upgrade --- app/build.gradle | 19 +++++++++--------- .../ui/base/BaseBottomSheetFragment.kt | 4 ++-- .../ui/views/drawer/HasherOfMenuItem.kt | 2 +- .../database/MigrationTestHelper.java | 14 ++++++------- build.gradle | 20 +++++++++---------- commons_compress_7z/build.gradle | 2 +- file_operations/build.gradle | 4 ++-- 7 files changed, 32 insertions(+), 33 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 34cd3e4b97..c6a4ccd3b7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,7 @@ apply plugin: 'com.hiya.jacoco-android' apply plugin: "com.starter.easylauncher" android { - compileSdkVersion 31 + compileSdkVersion 33 packagingOptions { resources { excludes += ['proguard-project.txt', 'project.properties', 'META-INF/LICENSE.txt', 'META-INF/LICENSE', 'META-INF/NOTICE.txt', 'META-INF/NOTICE', 'META-INF/DEPENDENCIES.txt', 'META-INF/DEPENDENCIES'] @@ -17,7 +17,7 @@ android { defaultConfig { applicationId "com.amaze.filemanager" minSdkVersion 19 - targetSdkVersion 31 + targetSdkVersion 33 versionCode 118 versionName "3.8.5" multiDexEnabled true @@ -85,13 +85,12 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' - useIR = true + jvmTarget = '11' } testOptions { @@ -254,11 +253,11 @@ dependencies { configurations.all { resolutionStrategy { dependencySubstitution { - substitute module("commons-logging:commons-logging-api:1.1") with module("commons-logging:commons-logging:1.1.1") - substitute module("com.android.support:support-annotations:27.1.1") with module("com.android.support:support-annotations:27.0.2") + substitute module("commons-logging:commons-logging-api:1.1") using module("commons-logging:commons-logging:1.1.1") + substitute module("com.android.support:support-annotations:27.1.1") using module("com.android.support:support-annotations:27.0.2") // These two lines are added to prevent possible class clashes between awaitility (which uses hamcrest 2.1) and junit (which uses hamcrest 1.3). - substitute module('org.hamcrest:hamcrest-core:1.3') with module("org.hamcrest:hamcrest:2.1") - substitute module('org.hamcrest:hamcrest-library:1.3') with module("org.hamcrest:hamcrest:2.1") + substitute module('org.hamcrest:hamcrest-core:1.3') using module("org.hamcrest:hamcrest:2.1") + substitute module('org.hamcrest:hamcrest-library:1.3') using module("org.hamcrest:hamcrest:2.1") } } } diff --git a/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt b/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt index 78c3b6449f..c8e6551fa8 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt +++ b/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt @@ -39,7 +39,7 @@ open class BaseBottomSheetFragment : BottomSheetDialogFragment() { * Initializes bottom sheet ui resources based on current theme */ fun initDialogResources(rootView: View) { - when ((activity as ThemedActivity?)!!.appTheme!!) { + when ((requireActivity() as ThemedActivity).appTheme!!) { AppTheme.DARK -> { rootView.setBackgroundDrawable( context?.resources?.getDrawable( @@ -54,7 +54,7 @@ open class BaseBottomSheetFragment : BottomSheetDialogFragment() { ) ) } - AppTheme.LIGHT, AppTheme.TIMED -> { + AppTheme.LIGHT, AppTheme.TIMED, AppTheme.SYSTEM -> { rootView .setBackgroundDrawable( context?.resources?.getDrawable( diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt b/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt index 1e09c91473..bbf04494d1 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt +++ b/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt @@ -28,7 +28,7 @@ import android.view.MenuItem data class HasherOfMenuItem( val groupId: Int, val itemId: Int, - val title: CharSequence, + val title: CharSequence?, val ordering: Int ) diff --git a/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java b/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java index d5dcacc0c7..e5094cfa30 100644 --- a/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java +++ b/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java @@ -477,7 +477,7 @@ static class MigratingDelegate extends MigrationTestHelper.RoomOpenHelperDelegat } @Override - protected void createAllTables(SupportSQLiteDatabase database) { + public void createAllTables(SupportSQLiteDatabase database) { throw new UnsupportedOperationException( "Was expecting to migrate but received create." + "Make sure you have created the database first."); @@ -485,7 +485,7 @@ protected void createAllTables(SupportSQLiteDatabase database) { @NonNull @Override - protected RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { + public RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { final Map tables = mDatabaseBundle.getEntitiesByTableName(); for (EntityBundle entity : tables.values()) { if (entity instanceof FtsEntityBundle) { @@ -548,7 +548,7 @@ static class CreatingDelegate extends MigrationTestHelper.RoomOpenHelperDelegate } @Override - protected void createAllTables(SupportSQLiteDatabase database) { + public void createAllTables(SupportSQLiteDatabase database) { for (String query : mDatabaseBundle.buildCreateQueries()) { database.execSQL(query); } @@ -556,7 +556,7 @@ protected void createAllTables(SupportSQLiteDatabase database) { @NonNull @Override - protected RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { + public RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { throw new UnsupportedOperationException( "This open helper just creates the database but" + " it received a migration request."); } @@ -571,14 +571,14 @@ abstract static class RoomOpenHelperDelegate extends RoomOpenHelper.Delegate { } @Override - protected void dropAllTables(SupportSQLiteDatabase database) { + public void dropAllTables(SupportSQLiteDatabase database) { throw new UnsupportedOperationException("cannot drop all tables in the test"); } @Override - protected void onCreate(SupportSQLiteDatabase database) {} + public void onCreate(SupportSQLiteDatabase database) {} @Override - protected void onOpen(SupportSQLiteDatabase database) {} + public void onOpen(SupportSQLiteDatabase database) {} } } diff --git a/build.gradle b/build.gradle index 94f25bf6b9..18909ccf8e 100644 --- a/build.gradle +++ b/build.gradle @@ -2,23 +2,23 @@ buildscript { ext { - kotlin_version = "1.6.10" + kotlin_version = "1.8.0" robolectricVersion = '4.9' glideVersion = '4.11.0' sshjVersion = '0.34.0' jcifsVersion = '2.1.6' fabSpeedDialVersion = '3.1.1' - roomVersion = '2.4.3' + roomVersion = '2.5.0' bouncyCastleVersion = '1.70' awaitilityVersion = "3.1.6" androidXCoreVersion = "1.7.0" - androidMaterialVersion = "1.4.0" // Upgrade to 1.5 requires targetSdkVersion 31 - androidXFragmentVersion = "1.4.1" - androidXAppCompatVersion = "1.4.1" - androidXAnnotationVersion = "1.3.0" + androidMaterialVersion = "1.5.0" // Upgrade to 1.5 requires targetSdkVersion 31 + androidXFragmentVersion = "1.5.5" + androidXAppCompatVersion = "1.6.1" + androidXAnnotationVersion = "1.5.0" androidXPrefVersion = "1.2.0" - androidXTestVersion = "1.4.0" - androidXTestExtVersion = "1.1.3" + androidXTestVersion = "1.5.0" + androidXTestExtVersion = "1.1.5" uiAutomatorVersion = "2.2.0" junitVersion = "4.13.2" slf4jVersion = "1.7.25" @@ -27,7 +27,7 @@ buildscript { androidBillingVersion = "5.0.0" junrarVersion = "7.4.0" zip4jVersion = "2.6.4" - espressoVersion = "3.4.0" + espressoVersion = "3.5.1" materialDialogsVersion = "0.9.6.0" jacocoVersion = "0.8.7" commonsCompressVersion = "1.22" @@ -66,7 +66,7 @@ allprojects { maven { url "https://jcenter.bintray.com" } } tasks.withType(Test) { - maxParallelForks = 4 + maxParallelForks = 8 maxHeapSize = "2g" forkEvery = 4 failFast = true diff --git a/commons_compress_7z/build.gradle b/commons_compress_7z/build.gradle index 0b7e3a9e9a..428e80db73 100644 --- a/commons_compress_7z/build.gradle +++ b/commons_compress_7z/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 33 defaultConfig { minSdkVersion 19 diff --git a/file_operations/build.gradle b/file_operations/build.gradle index eadddd661e..47cefa5e63 100644 --- a/file_operations/build.gradle +++ b/file_operations/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 30 + compileSdkVersion 33 defaultConfig { minSdkVersion 19 @@ -51,7 +51,7 @@ android { } kotlinOptions { - useIR = true + jvmTarget = '11' } } From 356068d69786630313083bfc9ec8f10f95680843 Mon Sep 17 00:00:00 2001 From: Raymond Lai Date: Sat, 18 Feb 2023 11:40:45 +0800 Subject: [PATCH 2/6] SDK 33 adaptations + lib upgrades It has to happen anyway. - Compile with SDK 33 - Use Kotlin 1.8 - Use Java 11 - Library upgrades - Fix syntax and API problems brought by the upgrade --- app/build.gradle | 19 +++++++++--------- .../ui/base/BaseBottomSheetFragment.kt | 4 ++-- .../ui/views/drawer/HasherOfMenuItem.kt | 2 +- .../database/MigrationTestHelper.java | 14 ++++++------- build.gradle | 20 +++++++++---------- commons_compress_7z/build.gradle | 2 +- file_operations/build.gradle | 4 ++-- 7 files changed, 32 insertions(+), 33 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index eeafa75fb6..204cd68677 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,7 @@ apply plugin: 'com.hiya.jacoco-android' apply plugin: "com.starter.easylauncher" android { - compileSdkVersion 31 + compileSdkVersion 33 packagingOptions { resources { excludes += ['proguard-project.txt', 'project.properties', 'META-INF/LICENSE.txt', 'META-INF/LICENSE', 'META-INF/NOTICE.txt', 'META-INF/NOTICE', 'META-INF/DEPENDENCIES.txt', 'META-INF/DEPENDENCIES'] @@ -17,7 +17,7 @@ android { defaultConfig { applicationId "com.amaze.filemanager" minSdkVersion 19 - targetSdkVersion 31 + targetSdkVersion 33 versionCode 118 versionName "3.8.5" multiDexEnabled true @@ -85,13 +85,12 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' - useIR = true + jvmTarget = '11' } testOptions { @@ -252,11 +251,11 @@ dependencies { configurations.all { resolutionStrategy { dependencySubstitution { - substitute module("commons-logging:commons-logging-api:1.1") with module("commons-logging:commons-logging:1.1.1") - substitute module("com.android.support:support-annotations:27.1.1") with module("com.android.support:support-annotations:27.0.2") + substitute module("commons-logging:commons-logging-api:1.1") using module("commons-logging:commons-logging:1.1.1") + substitute module("com.android.support:support-annotations:27.1.1") using module("com.android.support:support-annotations:27.0.2") // These two lines are added to prevent possible class clashes between awaitility (which uses hamcrest 2.1) and junit (which uses hamcrest 1.3). - substitute module('org.hamcrest:hamcrest-core:1.3') with module("org.hamcrest:hamcrest:2.1") - substitute module('org.hamcrest:hamcrest-library:1.3') with module("org.hamcrest:hamcrest:2.1") + substitute module('org.hamcrest:hamcrest-core:1.3') using module("org.hamcrest:hamcrest:2.1") + substitute module('org.hamcrest:hamcrest-library:1.3') using module("org.hamcrest:hamcrest:2.1") } } } diff --git a/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt b/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt index 78c3b6449f..c8e6551fa8 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt +++ b/app/src/main/java/com/amaze/filemanager/ui/base/BaseBottomSheetFragment.kt @@ -39,7 +39,7 @@ open class BaseBottomSheetFragment : BottomSheetDialogFragment() { * Initializes bottom sheet ui resources based on current theme */ fun initDialogResources(rootView: View) { - when ((activity as ThemedActivity?)!!.appTheme!!) { + when ((requireActivity() as ThemedActivity).appTheme!!) { AppTheme.DARK -> { rootView.setBackgroundDrawable( context?.resources?.getDrawable( @@ -54,7 +54,7 @@ open class BaseBottomSheetFragment : BottomSheetDialogFragment() { ) ) } - AppTheme.LIGHT, AppTheme.TIMED -> { + AppTheme.LIGHT, AppTheme.TIMED, AppTheme.SYSTEM -> { rootView .setBackgroundDrawable( context?.resources?.getDrawable( diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt b/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt index 1e09c91473..bbf04494d1 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt +++ b/app/src/main/java/com/amaze/filemanager/ui/views/drawer/HasherOfMenuItem.kt @@ -28,7 +28,7 @@ import android.view.MenuItem data class HasherOfMenuItem( val groupId: Int, val itemId: Int, - val title: CharSequence, + val title: CharSequence?, val ordering: Int ) diff --git a/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java b/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java index d5dcacc0c7..e5094cfa30 100644 --- a/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java +++ b/app/src/test/java/com/amaze/filemanager/database/MigrationTestHelper.java @@ -477,7 +477,7 @@ static class MigratingDelegate extends MigrationTestHelper.RoomOpenHelperDelegat } @Override - protected void createAllTables(SupportSQLiteDatabase database) { + public void createAllTables(SupportSQLiteDatabase database) { throw new UnsupportedOperationException( "Was expecting to migrate but received create." + "Make sure you have created the database first."); @@ -485,7 +485,7 @@ protected void createAllTables(SupportSQLiteDatabase database) { @NonNull @Override - protected RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { + public RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { final Map tables = mDatabaseBundle.getEntitiesByTableName(); for (EntityBundle entity : tables.values()) { if (entity instanceof FtsEntityBundle) { @@ -548,7 +548,7 @@ static class CreatingDelegate extends MigrationTestHelper.RoomOpenHelperDelegate } @Override - protected void createAllTables(SupportSQLiteDatabase database) { + public void createAllTables(SupportSQLiteDatabase database) { for (String query : mDatabaseBundle.buildCreateQueries()) { database.execSQL(query); } @@ -556,7 +556,7 @@ protected void createAllTables(SupportSQLiteDatabase database) { @NonNull @Override - protected RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { + public RoomOpenHelper.ValidationResult onValidateSchema(@NonNull SupportSQLiteDatabase db) { throw new UnsupportedOperationException( "This open helper just creates the database but" + " it received a migration request."); } @@ -571,14 +571,14 @@ abstract static class RoomOpenHelperDelegate extends RoomOpenHelper.Delegate { } @Override - protected void dropAllTables(SupportSQLiteDatabase database) { + public void dropAllTables(SupportSQLiteDatabase database) { throw new UnsupportedOperationException("cannot drop all tables in the test"); } @Override - protected void onCreate(SupportSQLiteDatabase database) {} + public void onCreate(SupportSQLiteDatabase database) {} @Override - protected void onOpen(SupportSQLiteDatabase database) {} + public void onOpen(SupportSQLiteDatabase database) {} } } diff --git a/build.gradle b/build.gradle index 3fd0ef3566..1d9736c176 100644 --- a/build.gradle +++ b/build.gradle @@ -2,23 +2,23 @@ buildscript { ext { - kotlin_version = "1.6.10" + kotlin_version = "1.8.0" robolectricVersion = '4.9' glideVersion = '4.11.0' sshjVersion = '0.34.0' jcifsVersion = '2.1.6' fabSpeedDialVersion = '3.1.1' - roomVersion = '2.4.3' + roomVersion = '2.5.0' bouncyCastleVersion = '1.70' awaitilityVersion = "3.1.6" androidXCoreVersion = "1.7.0" - androidMaterialVersion = "1.4.0" // Upgrade to 1.5 requires targetSdkVersion 31 - androidXFragmentVersion = "1.4.1" - androidXAppCompatVersion = "1.4.1" - androidXAnnotationVersion = "1.3.0" + androidMaterialVersion = "1.5.0" // Upgrade to 1.5 requires targetSdkVersion 31 + androidXFragmentVersion = "1.5.5" + androidXAppCompatVersion = "1.6.1" + androidXAnnotationVersion = "1.5.0" androidXPrefVersion = "1.2.0" - androidXTestVersion = "1.4.0" - androidXTestExtVersion = "1.1.3" + androidXTestVersion = "1.5.0" + androidXTestExtVersion = "1.1.5" uiAutomatorVersion = "2.2.0" junitVersion = "4.13.2" slf4jVersion = "1.7.25" @@ -27,7 +27,7 @@ buildscript { androidBillingVersion = "5.0.0" junrarVersion = "7.4.0" zip4jVersion = "2.6.4" - espressoVersion = "3.4.0" + espressoVersion = "3.5.1" materialDialogsVersion = "0.9.6.0" jacocoVersion = "0.8.7" commonsCompressVersion = "1.22" @@ -68,7 +68,7 @@ allprojects { maven { url "https://jcenter.bintray.com" } } tasks.withType(Test) { - maxParallelForks = 4 + maxParallelForks = 8 maxHeapSize = "2g" forkEvery = 4 failFast = true diff --git a/commons_compress_7z/build.gradle b/commons_compress_7z/build.gradle index 0b7e3a9e9a..428e80db73 100644 --- a/commons_compress_7z/build.gradle +++ b/commons_compress_7z/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 33 defaultConfig { minSdkVersion 19 diff --git a/file_operations/build.gradle b/file_operations/build.gradle index eadddd661e..47cefa5e63 100644 --- a/file_operations/build.gradle +++ b/file_operations/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 30 + compileSdkVersion 33 defaultConfig { minSdkVersion 19 @@ -51,7 +51,7 @@ android { } kotlinOptions { - useIR = true + jvmTarget = '11' } } From 43d148f5380bb6c2d783757bd466932e36265159 Mon Sep 17 00:00:00 2001 From: Raymond Lai Date: Thu, 20 Jul 2023 00:17:07 +0800 Subject: [PATCH 3/6] Changes per feedback Add POST_NOTIFICATION permission request --- app/src/main/AndroidManifest.xml | 1 + .../ui/activities/MainActivity.java | 7 +++- .../superclasses/PermissionsActivity.java | 38 +++++++++++++++++-- app/src/main/res/values/strings.xml | 2 + 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 96ff20b8a3..5bd6da5ace 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,6 +39,7 @@ + = Build.VERSION_CODES.M) { + if (SDK_INT >= Build.VERSION_CODES.M) { if (!checkStoragePermission()) { requestStoragePermission(this, true); } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (SDK_INT >= Build.VERSION_CODES.R) { requestAllFilesAccess(this); } + if (SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + requestNotificationPermission(true); + } } } diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java index 9c97929871..c0bd3a31a9 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java @@ -20,6 +20,8 @@ package com.amaze.filemanager.ui.activities.superclasses; +import static android.os.Build.VERSION_CODES.TIRAMISU; + import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import com.amaze.filemanager.R; @@ -48,10 +50,11 @@ public class PermissionsActivity extends ThemedActivity private static final String TAG = PermissionsActivity.class.getSimpleName(); - public static final int PERMISSION_LENGTH = 3; + public static final int PERMISSION_LENGTH = 4; public static final int STORAGE_PERMISSION = 0, INSTALL_APK_PERMISSION = 1, - ALL_FILES_PERMISSION = 2; + ALL_FILES_PERMISSION = 2, + NOTIFICATION_PERMISSION = 3; private final OnPermissionGranted[] permissionCallbacks = new OnPermissionGranted[PERMISSION_LENGTH]; @@ -69,7 +72,13 @@ public void onRequestPermissionsResult( Toast.makeText(this, R.string.grantfailed, Toast.LENGTH_SHORT).show(); requestStoragePermission(permissionCallbacks[STORAGE_PERMISSION], false); } - + } else if (requestCode == NOTIFICATION_PERMISSION && Build.VERSION.SDK_INT >= TIRAMISU) { + if (isGranted(grantResults)) { + Utils.enableScreenRotation(this); + } else { + Toast.makeText(this, R.string.grantfailed, Toast.LENGTH_SHORT).show(); + requestNotificationPermission(false); + } } else if (requestCode == INSTALL_APK_PERMISSION) { if (isGranted(grantResults)) { permissionCallbacks[INSTALL_APK_PERMISSION].onPermissionGranted(); @@ -84,6 +93,29 @@ public boolean checkStoragePermission() { == PackageManager.PERMISSION_GRANTED; } + @RequiresApi(api = TIRAMISU) + public void requestNotificationPermission(boolean isInitialStart) { + Utils.disableScreenRotation(this); + final MaterialDialog materialDialog = + GeneralDialogCreation.showBasicDialog( + this, + R.string.grant_notification_permission, + R.string.grantper, + R.string.grant, + R.string.cancel); + materialDialog.getActionButton(DialogAction.NEGATIVE).setOnClickListener(v -> finish()); + materialDialog.setCancelable(false); + + requestPermission( + Manifest.permission.POST_NOTIFICATIONS, + NOTIFICATION_PERMISSION, + materialDialog, + () -> { + //do nothing + }, + isInitialStart); + } + public void requestStoragePermission( @NonNull final OnPermissionGranted onPermissionGranted, boolean isInitialStart) { Utils.disableScreenRotation(this); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8fc0ca66fc..8bec20b847 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -813,5 +813,7 @@ You only need to do this once, until the next time you select a new location for Try Indexed Search! Recent Results + + Amaze needs notification permission to display file operation progress, as well as a handy panel to start/stop the FTP server. From b71b711551234ffae824a8d11af9cfb488e53913 Mon Sep 17 00:00:00 2001 From: Raymond Lai Date: Thu, 20 Jul 2023 00:17:07 +0800 Subject: [PATCH 4/6] Changes per feedback - Add POST_NOTIFICATION permission request - Add additional permissions required by API 33 for storage access --- .../ftp/FtpServiceStaticMethodsTest.kt | 5 ++- .../security/SecretKeygenEspressoTest.kt | 2 + app/src/main/AndroidManifest.xml | 5 +++ .../ui/activities/MainActivity.java | 7 ++- .../superclasses/PermissionsActivity.java | 44 +++++++++++++++++-- app/src/main/res/values/strings.xml | 2 + 6 files changed, 58 insertions(+), 7 deletions(-) diff --git a/app/src/androidTest/java/com/amaze/filemanager/asynchronous/services/ftp/FtpServiceStaticMethodsTest.kt b/app/src/androidTest/java/com/amaze/filemanager/asynchronous/services/ftp/FtpServiceStaticMethodsTest.kt index 830e55fe91..afa89840a9 100644 --- a/app/src/androidTest/java/com/amaze/filemanager/asynchronous/services/ftp/FtpServiceStaticMethodsTest.kt +++ b/app/src/androidTest/java/com/amaze/filemanager/asynchronous/services/ftp/FtpServiceStaticMethodsTest.kt @@ -26,6 +26,7 @@ import android.os.Build.VERSION_CODES.N_MR1 import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.amaze.filemanager.utils.NetworkUtil import org.junit.Assert.assertNotNull import org.junit.Assert.fail import org.junit.Test @@ -53,11 +54,11 @@ class FtpServiceStaticMethodsTest { */ if (SDK_INT >= N_MR1) { ApplicationProvider.getApplicationContext().run { - if (!FtpService.isConnectedToLocalNetwork(this)) { + if (!NetworkUtil.isConnectedToLocalNetwork(this)) { fail("Please connect your device to network to run this test!") } - FtpService.getLocalInetAddress(this).also { + NetworkUtil.getLocalInetAddress(this).also { assertNotNull(it) assertNotNull(it?.hostAddress) } diff --git a/app/src/androidTest/java/com/amaze/filemanager/utils/security/SecretKeygenEspressoTest.kt b/app/src/androidTest/java/com/amaze/filemanager/utils/security/SecretKeygenEspressoTest.kt index 773113c169..293accbf3e 100644 --- a/app/src/androidTest/java/com/amaze/filemanager/utils/security/SecretKeygenEspressoTest.kt +++ b/app/src/androidTest/java/com/amaze/filemanager/utils/security/SecretKeygenEspressoTest.kt @@ -51,6 +51,8 @@ class SecretKeygenEspressoTest { assertEquals("aes", this.algorithm.lowercase()) } ?: if (SDK_INT < ICE_CREAM_SANDWICH) { fail("Android version not supported") + } else { + // do nothing } } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 96ff20b8a3..92c271bee6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,6 +29,7 @@ + @@ -39,6 +40,10 @@ + + + + = Build.VERSION_CODES.M) { + if (SDK_INT >= Build.VERSION_CODES.M) { if (!checkStoragePermission()) { requestStoragePermission(this, true); } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (SDK_INT >= Build.VERSION_CODES.R) { requestAllFilesAccess(this); } + if (SDK_INT >= Build.VERSION_CODES.TIRAMISU && !checkNotificationPermission()) { + requestNotificationPermission(true); + } } } diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java index 9c97929871..7204cee67c 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java @@ -20,6 +20,8 @@ package com.amaze.filemanager.ui.activities.superclasses; +import static android.os.Build.VERSION_CODES.TIRAMISU; + import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import com.amaze.filemanager.R; @@ -48,10 +50,11 @@ public class PermissionsActivity extends ThemedActivity private static final String TAG = PermissionsActivity.class.getSimpleName(); - public static final int PERMISSION_LENGTH = 3; + public static final int PERMISSION_LENGTH = 4; public static final int STORAGE_PERMISSION = 0, INSTALL_APK_PERMISSION = 1, - ALL_FILES_PERMISSION = 2; + ALL_FILES_PERMISSION = 2, + NOTIFICATION_PERMISSION = 3; private final OnPermissionGranted[] permissionCallbacks = new OnPermissionGranted[PERMISSION_LENGTH]; @@ -69,7 +72,13 @@ public void onRequestPermissionsResult( Toast.makeText(this, R.string.grantfailed, Toast.LENGTH_SHORT).show(); requestStoragePermission(permissionCallbacks[STORAGE_PERMISSION], false); } - + } else if (requestCode == NOTIFICATION_PERMISSION && Build.VERSION.SDK_INT >= TIRAMISU) { + if (isGranted(grantResults)) { + Utils.enableScreenRotation(this); + } else { + Toast.makeText(this, R.string.grantfailed, Toast.LENGTH_SHORT).show(); + requestNotificationPermission(false); + } } else if (requestCode == INSTALL_APK_PERMISSION) { if (isGranted(grantResults)) { permissionCallbacks[INSTALL_APK_PERMISSION].onPermissionGranted(); @@ -84,6 +93,35 @@ public boolean checkStoragePermission() { == PackageManager.PERMISSION_GRANTED; } + @RequiresApi(TIRAMISU) + public boolean checkNotificationPermission() { + return ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) + == PackageManager.PERMISSION_GRANTED; + } + + @RequiresApi(TIRAMISU) + public void requestNotificationPermission(boolean isInitialStart) { + Utils.disableScreenRotation(this); + final MaterialDialog materialDialog = + GeneralDialogCreation.showBasicDialog( + this, + R.string.grant_notification_permission, + R.string.grantper, + R.string.grant, + R.string.cancel); + materialDialog.getActionButton(DialogAction.NEGATIVE).setOnClickListener(v -> finish()); + materialDialog.setCancelable(false); + + requestPermission( + Manifest.permission.POST_NOTIFICATIONS, + NOTIFICATION_PERMISSION, + materialDialog, + () -> { + // do nothing + }, + isInitialStart); + } + public void requestStoragePermission( @NonNull final OnPermissionGranted onPermissionGranted, boolean isInitialStart) { Utils.disableScreenRotation(this); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8fc0ca66fc..8bec20b847 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -813,5 +813,7 @@ You only need to do this once, until the next time you select a new location for Try Indexed Search! Recent Results + + Amaze needs notification permission to display file operation progress, as well as a handy panel to start/stop the FTP server. From 09fdaf3c3ee31bb931f5dd70100c1e56ae9289c3 Mon Sep 17 00:00:00 2001 From: Vishal Nehra Date: Fri, 21 Jul 2023 03:51:42 +0530 Subject: [PATCH 5/6] Modifications in asking storage permission in T --- .../ui/activities/MainActivity.java | 9 ++- .../superclasses/PermissionsActivity.java | 73 ++++++++++++------- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java index 455e88e98a..23c2eeb3e3 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java @@ -557,10 +557,11 @@ public void onPermissionGranted() { private void checkForExternalPermission() { if (SDK_INT >= Build.VERSION_CODES.M) { if (!checkStoragePermission()) { - requestStoragePermission(this, true); - } - if (SDK_INT >= Build.VERSION_CODES.R) { - requestAllFilesAccess(this); + if (SDK_INT >= Build.VERSION_CODES.R) { + requestAllFilesAccess(this); + } else { + requestStoragePermission(this, true); + } } if (SDK_INT >= Build.VERSION_CODES.TIRAMISU) { requestNotificationPermission(true); diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java index c0bd3a31a9..d8b374d3a9 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java @@ -20,12 +20,14 @@ package com.amaze.filemanager.ui.activities.superclasses; +import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION_CODES.TIRAMISU; import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import com.amaze.filemanager.R; import com.amaze.filemanager.application.AppConfig; +import com.amaze.filemanager.ui.activities.MainActivity; import com.amaze.filemanager.ui.dialogs.GeneralDialogCreation; import com.amaze.filemanager.utils.Utils; import com.google.android.material.snackbar.BaseTransientBottomBar; @@ -89,8 +91,13 @@ public void onRequestPermissionsResult( public boolean checkStoragePermission() { // Verify that all required contact permissions have been granted. - return ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED; + if (SDK_INT >= Build.VERSION_CODES.R) { + return ActivityCompat.checkSelfPermission(this, Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) + == PackageManager.PERMISSION_GRANTED; + } else { + return ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) + == PackageManager.PERMISSION_GRANTED; + } } @RequiresApi(api = TIRAMISU) @@ -192,18 +199,29 @@ private void requestPermission( } else if (isInitialStart) { ActivityCompat.requestPermissions(this, new String[] {permission}, code); } else { - Snackbar.make( - findViewById(R.id.content_frame), - R.string.grantfailed, - BaseTransientBottomBar.LENGTH_INDEFINITE) - .setAction( - R.string.grant, - v -> - startActivity( - new Intent( - android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, - Uri.parse(String.format("package:%s", getPackageName()))))) - .show(); + if (SDK_INT >= Build.VERSION_CODES.R) { + Snackbar.make( + findViewById(R.id.content_frame), + R.string.grantfailed, + BaseTransientBottomBar.LENGTH_INDEFINITE) + .setAction( + R.string.grant, + v -> requestAllFilesAccessPermission(onPermissionGranted)) + .show(); + } else { + Snackbar.make( + findViewById(R.id.content_frame), + R.string.grantfailed, + BaseTransientBottomBar.LENGTH_INDEFINITE) + .setAction( + R.string.grant, + v -> + startActivity( + new Intent( + android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.parse(String.format("package:%s", getPackageName()))))) + .show(); + } } } @@ -226,17 +244,7 @@ public void requestAllFilesAccess(@NonNull final OnPermissionGranted onPermissio .getActionButton(DialogAction.POSITIVE) .setOnClickListener( v -> { - Utils.disableScreenRotation(this); - permissionCallbacks[ALL_FILES_PERMISSION] = onPermissionGranted; - try { - Intent intent = - new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) - .setData(Uri.parse("package:" + getPackageName())); - startActivity(intent); - } catch (Exception e) { - Log.e(TAG, "Failed to initial activity to grant all files access", e); - AppConfig.toast(this, getString(R.string.grantfailed)); - } + requestAllFilesAccessPermission(onPermissionGranted); materialDialog.dismiss(); }); materialDialog.setCancelable(false); @@ -244,6 +252,21 @@ public void requestAllFilesAccess(@NonNull final OnPermissionGranted onPermissio } } + @RequiresApi(api = Build.VERSION_CODES.R) + private void requestAllFilesAccessPermission(@NonNull final OnPermissionGranted onPermissionGranted) { + Utils.disableScreenRotation(this); + permissionCallbacks[ALL_FILES_PERMISSION] = onPermissionGranted; + try { + Intent intent = + new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) + .setData(Uri.parse("package:" + getPackageName())); + startActivity(intent); + } catch (Exception e) { + Log.e(TAG, "Failed to initial activity to grant all files access", e); + AppConfig.toast(this, getString(R.string.grantfailed)); + } + } + private boolean isGranted(int[] grantResults) { return grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED; } From 4432ea712df94ab25baf461e26d066a1a2b6582f Mon Sep 17 00:00:00 2001 From: Raymond Lai Date: Fri, 21 Jul 2023 23:30:25 +0800 Subject: [PATCH 6/6] Fix codacy and spotless complaint Also enable use of jvmToolchain for Kotlin related compilation stuff. See https://youtrack.jetbrains.com/issue/KTIJ-24311/task-current-target-is-17-and-kaptGenerateStubsProductionDebugKotlin-task-current-target-is-1.8-jvm-target-compatibility-should#focus=Comments-27-6798448.0-0 for reason of the workaround --- app/build.gradle | 5 ++- .../superclasses/PermissionsActivity.java | 45 ++++++++++--------- file_operations/build.gradle | 8 +++- portscanner/build.gradle | 12 +++-- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9bd34bcebd..ee99efc317 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -251,6 +251,10 @@ dependencies { } +kotlin { + jvmToolchain(11) +} + configurations.all { resolutionStrategy { dependencySubstitution { @@ -305,7 +309,6 @@ tasks.withType(Test) { jacoco.excludes = ['jdk.internal.*'] } - Properties props = new Properties() def propFile = new File('signing.properties') diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java index eba49fc7d5..3ca97c186b 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/superclasses/PermissionsActivity.java @@ -20,8 +20,9 @@ package com.amaze.filemanager.ui.activities.superclasses; -import static android.os.Build.VERSION_CODES.TIRAMISU; import static android.os.Build.VERSION.SDK_INT; +import static android.os.Build.VERSION_CODES.TIRAMISU; + import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import com.amaze.filemanager.R; @@ -72,7 +73,7 @@ public void onRequestPermissionsResult( Toast.makeText(this, R.string.grantfailed, Toast.LENGTH_SHORT).show(); requestStoragePermission(permissionCallbacks[STORAGE_PERMISSION], false); } - } else if (requestCode == NOTIFICATION_PERMISSION && Build.VERSION.SDK_INT >= TIRAMISU) { + } else if (requestCode == NOTIFICATION_PERMISSION && SDK_INT >= TIRAMISU) { if (isGranted(grantResults)) { Utils.enableScreenRotation(this); } else { @@ -90,11 +91,12 @@ public void onRequestPermissionsResult( public boolean checkStoragePermission() { // Verify that all required contact permissions have been granted. if (SDK_INT >= Build.VERSION_CODES.R) { - return ActivityCompat.checkSelfPermission(this, Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) - == PackageManager.PERMISSION_GRANTED; + return ActivityCompat.checkSelfPermission( + this, Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) + == PackageManager.PERMISSION_GRANTED; } else { return ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED; + == PackageManager.PERMISSION_GRANTED; } } @@ -208,23 +210,21 @@ private void requestPermission( findViewById(R.id.content_frame), R.string.grantfailed, BaseTransientBottomBar.LENGTH_INDEFINITE) - .setAction( - R.string.grant, - v -> requestAllFilesAccessPermission(onPermissionGranted)) + .setAction(R.string.grant, v -> requestAllFilesAccessPermission(onPermissionGranted)) .show(); } else { Snackbar.make( - findViewById(R.id.content_frame), - R.string.grantfailed, - BaseTransientBottomBar.LENGTH_INDEFINITE) - .setAction( - R.string.grant, - v -> - startActivity( - new Intent( - android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, - Uri.parse(String.format("package:%s", getPackageName()))))) - .show(); + findViewById(R.id.content_frame), + R.string.grantfailed, + BaseTransientBottomBar.LENGTH_INDEFINITE) + .setAction( + R.string.grant, + v -> + startActivity( + new Intent( + android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.parse(String.format("package:%s", getPackageName()))))) + .show(); } } } @@ -257,13 +257,14 @@ public void requestAllFilesAccess(@NonNull final OnPermissionGranted onPermissio } @RequiresApi(api = Build.VERSION_CODES.R) - private void requestAllFilesAccessPermission(@NonNull final OnPermissionGranted onPermissionGranted) { + private void requestAllFilesAccessPermission( + @NonNull final OnPermissionGranted onPermissionGranted) { Utils.disableScreenRotation(this); permissionCallbacks[ALL_FILES_PERMISSION] = onPermissionGranted; try { Intent intent = - new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) - .setData(Uri.parse("package:" + getPackageName())); + new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) + .setData(Uri.parse("package:" + getPackageName())); startActivity(intent); } catch (Exception e) { Log.e(TAG, "Failed to initial activity to grant all files access", e); diff --git a/file_operations/build.gradle b/file_operations/build.gradle index 47cefa5e63..1caa72ac33 100644 --- a/file_operations/build.gradle +++ b/file_operations/build.gradle @@ -32,8 +32,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } testOptions { @@ -55,6 +55,10 @@ android { } } +kotlin { + jvmToolchain(11) +} + dependencies { modules { module("org.bouncycastle:bcprov-jdk15to18") { diff --git a/portscanner/build.gradle b/portscanner/build.gradle index 355d17f1c3..65b6b3e2f0 100644 --- a/portscanner/build.gradle +++ b/portscanner/build.gradle @@ -5,11 +5,11 @@ apply plugin: 'kotlin-parcelize' android { namespace 'com.stealthcopter.networktools' - compileSdk 32 + compileSdk 33 defaultConfig { minSdk 14 - targetSdk 32 + targetSdk 33 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" @@ -22,11 +22,15 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } } +kotlin { + jvmToolchain(11) +} + dependencies { implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion" // Because RxAndroid releases are few and far between, it is recommended you also