diff --git a/app/build.gradle b/app/build.gradle index 0f54e63352..7e20f6c638 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,9 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-kapt' +apply plugin: 'com.google.devtools.ksp' +// KAPT removed - Glide 4.16.0 supports KSP, eliminating the need for KAPT apply plugin: 'kotlin-parcelize' -apply plugin: 'com.hiya.jacoco-android' +apply plugin: 'jacoco' apply plugin: "com.starter.easylauncher" android { @@ -26,13 +27,8 @@ android { vectorDrawables.useSupportLibrary = true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - javaCompileOptions { - annotationProcessorOptions { - arguments += ["room.schemaLocation" : "$projectDir/src/test/resources/schemas".toString(), - "room.incremental" : "true", - "room.expandProjection": "true"] - } - } + // Room configuration is now handled by KSP (see ksp block below) + // javaCompileOptions are kept for any other annotation processors that might need them } signingConfigs { @@ -63,6 +59,8 @@ android { buildFeatures { viewBinding true + // Required on AGP 8+ when using custom BuildConfig fields + buildConfig true } flavorDimensions = ['static'] @@ -85,12 +83,12 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = '17' } testOptions { @@ -127,10 +125,10 @@ dependencies { implementation 'androidx.cardview:cardview:1.0.0' implementation "androidx.room:room-runtime:$roomVersion" playImplementation "com.android.billingclient:billing:$androidBillingVersion" - kapt "androidx.room:room-compiler:$roomVersion" + ksp "androidx.room:room-compiler:$roomVersion" // RxJava support for Room implementation "androidx.room:room-rxjava2:$roomVersion" - kapt "androidx.annotation:annotation:$androidXAnnotationVersion" + ksp "androidx.annotation:annotation:$androidXAnnotationVersion" implementation "androidx.preference:preference-ktx:$androidXPrefVersion" @@ -153,7 +151,7 @@ dependencies { testImplementation "io.mockk:mockk:$mockkVersion" testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinxCoroutineTestVersion" testImplementation "androidx.arch.core:core-testing:$androidXArchCoreTestVersion" - kaptTest "com.google.auto.service:auto-service:1.0-rc4" + kspTest "com.google.auto.service:auto-service:1.0-rc4" androidTestImplementation "junit:junit:$junitVersion"//tests the app logic androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion" @@ -219,7 +217,10 @@ dependencies { // Excludes the support library because it's already included by Glide. transitive = false } - kapt "com.github.bumptech.glide:compiler:$glideVersion" + // Use KSP for Glide (Glide 4.12.0+ supports KSP) + // This eliminates the need for KAPT entirely, avoiding Windows SQLite native library issues + // Use the ksp artifact for Glide to generate GlideApp + ksp "com.github.bumptech.glide:ksp:$glideVersion" implementation "com.leinardi.android:speed-dial:$fabSpeedDialVersion" @@ -257,9 +258,22 @@ dependencies { } kotlin { - jvmToolchain(11) + jvmToolchain(17) } + +// KSP (Kotlin Symbol Processing) configuration +// KSP is faster than KAPT and doesn't have the Windows native library extraction issues +// KSP automatically handles task dependencies, so no manual configuration is needed +ksp { + arg("room.schemaLocation", "$projectDir/src/test/resources/schemas") + arg("room.incremental", "true") + arg("room.expandProjection", "true") +} + +// KAPT has been completely removed - both Room and Glide now use KSP +// This eliminates Windows SQLite native library issues that occurred with KAPT + configurations.configureEach { resolutionStrategy { dependencySubstitution { @@ -295,15 +309,6 @@ project.afterEvaluate { clean.dependsOn supportOldLangCodes clean.mustRunAfter supportOldLangCodes -jacoco { - toolVersion = "${jacocoVersion}" -} - -jacocoAndroidUnitTestReport { - html.enabled true - xml.enabled true -} - tasks.withType(Test).configureEach { jacoco.includeNoLocationClasses = true jacoco.excludes = ['jdk.internal.*'] diff --git a/app/src/main/java/com/amaze/filemanager/adapters/CompressedExplorerAdapter.java b/app/src/main/java/com/amaze/filemanager/adapters/CompressedExplorerAdapter.java index 73b6e2bb07..b8fd37c4c6 100644 --- a/app/src/main/java/com/amaze/filemanager/adapters/CompressedExplorerAdapter.java +++ b/app/src/main/java/com/amaze/filemanager/adapters/CompressedExplorerAdapter.java @@ -23,7 +23,7 @@ import java.util.ArrayList; import java.util.List; -import com.amaze.filemanager.GlideApp; +import com.bumptech.glide.Glide; import com.amaze.filemanager.R; import com.amaze.filemanager.adapters.data.CompressedObjectParcelable; import com.amaze.filemanager.adapters.holders.CompressedItemViewHolder; @@ -240,7 +240,7 @@ public void onBindViewHolder(final CompressedItemViewHolder holder, int position compressedExplorerFragment.getResources().getDisplayMetrics())); if (rowItem.type == CompressedObjectParcelable.TYPE_GOBACK) { - GlideApp.with(compressedExplorerFragment) + Glide.with(compressedExplorerFragment) .load(R.drawable.ic_arrow_left_white_24dp) .into(holder.genericIcon); gradientDrawable.setColor(Utils.getColor(context, R.color.goback_item)); @@ -248,7 +248,7 @@ public void onBindViewHolder(final CompressedItemViewHolder holder, int position holder.txtDesc.setText(""); holder.date.setText(R.string.goback); } else { - GlideApp.with(compressedExplorerFragment) + Glide.with(compressedExplorerFragment) .load(rowItem.iconData.image) .into(holder.genericIcon); diff --git a/app/src/main/java/com/amaze/filemanager/adapters/RecyclerAdapter.java b/app/src/main/java/com/amaze/filemanager/adapters/RecyclerAdapter.java index e860332277..7f72fd0443 100644 --- a/app/src/main/java/com/amaze/filemanager/adapters/RecyclerAdapter.java +++ b/app/src/main/java/com/amaze/filemanager/adapters/RecyclerAdapter.java @@ -38,7 +38,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.amaze.filemanager.GlideApp; +import com.bumptech.glide.Glide; import com.amaze.filemanager.R; import com.amaze.filemanager.adapters.data.IconDataParcelable; import com.amaze.filemanager.adapters.data.LayoutElementParcelable; @@ -616,7 +616,7 @@ private void setItems( preloader = new RecyclerViewPreloader<>( - GlideApp.with(mainFragment), + Glide.with(mainFragment), modelProvider, sizeProvider, GlideConstants.MAX_PRELOAD_FILES); @@ -807,10 +807,10 @@ && getItemsDigested().get(holder.getAdapterPosition()).getChecked() }); // clear previously cached icon - GlideApp.with(mainFragment).clear(holder.genericIcon); - GlideApp.with(mainFragment).clear(holder.pictureIcon); - GlideApp.with(mainFragment).clear(holder.apkIcon); - GlideApp.with(mainFragment).clear(holder.baseItemView); + Glide.with(mainFragment).clear(holder.genericIcon); + Glide.with(mainFragment).clear(holder.pictureIcon); + Glide.with(mainFragment).clear(holder.apkIcon); + Glide.with(mainFragment).clear(holder.baseItemView); holder.baseItemView.setOnClickListener( v -> { @@ -1023,10 +1023,10 @@ && getItemsDigested().get(holder.getAdapterPosition()).getChecked() // view is a grid view // clear previously cached icon - GlideApp.with(mainFragment).clear(holder.genericIcon); - GlideApp.with(mainFragment).clear(holder.iconLayout); - GlideApp.with(mainFragment).clear(holder.imageView1); - GlideApp.with(mainFragment).clear(holder.baseItemView); + Glide.with(mainFragment).clear(holder.genericIcon); + Glide.with(mainFragment).clear(holder.iconLayout); + Glide.with(mainFragment).clear(holder.imageView1); + Glide.with(mainFragment).clear(holder.baseItemView); holder.checkImageViewGrid.setColorFilter(accentColor); holder.baseItemView.setOnClickListener( @@ -1061,7 +1061,7 @@ && getItemsDigested().get(holder.getAdapterPosition()).getChecked() holder.genericIcon.setImageResource(R.drawable.ic_doc_apk_white); } } else { - GlideApp.with(mainFragment).load(rowItem.iconData.image).into(holder.genericIcon); + Glide.with(mainFragment).load(rowItem.iconData.image).into(holder.genericIcon); } if (holder.genericIcon.getVisibility() == View.VISIBLE) { @@ -1275,7 +1275,7 @@ private void showThumbnailWithBackground( OnImageProcessed errorListener) { if (iconData.isImageBroken()) { viewHolder.genericIcon.setVisibility(View.VISIBLE); - GlideApp.with(mainFragment) + Glide.with(mainFragment) .load(R.drawable.ic_broken_image_white_24dp) .into(viewHolder.genericIcon); GradientDrawable gradientDrawable = (GradientDrawable) viewHolder.genericIcon.getBackground(); @@ -1286,7 +1286,7 @@ private void showThumbnailWithBackground( } viewHolder.genericIcon.setVisibility(View.VISIBLE); - GlideApp.with(mainFragment).load(iconData.loadingImage).into(viewHolder.genericIcon); + Glide.with(mainFragment).load(iconData.loadingImage).into(viewHolder.genericIcon); GradientDrawable gradientDrawable = (GradientDrawable) viewHolder.genericIcon.getBackground(); RequestListener requestListener = @@ -1298,7 +1298,7 @@ public boolean onLoadFailed( new Handler( msg -> { viewHolder.genericIcon.setVisibility(View.VISIBLE); - GlideApp.with(mainFragment) + Glide.with(mainFragment) .load(R.drawable.ic_broken_image_white_24dp) .into(viewHolder.genericIcon); return false; @@ -1344,7 +1344,7 @@ private void showRoundedThumbnail( viewHolder.genericIcon.setVisibility(View.VISIBLE); iconBackground.setBackgroundColor(grey_color); - GlideApp.with(mainFragment) + Glide.with(mainFragment) .load(R.drawable.ic_broken_image_white_24dp) .into(viewHolder.genericIcon); view.setVisibility(View.INVISIBLE); @@ -1357,7 +1357,7 @@ private void showRoundedThumbnail( getBoolean(PREFERENCE_USE_CIRCULAR_IMAGES) ? viewHolder.genericIcon : viewHolder.iconLayout; viewHolder.genericIcon.setVisibility(View.VISIBLE); - GlideApp.with(mainFragment).load(iconData.loadingImage).into(viewHolder.genericIcon); + Glide.with(mainFragment).load(iconData.loadingImage).into(viewHolder.genericIcon); view.setVisibility(View.INVISIBLE); RequestListener requestListener = @@ -1368,7 +1368,7 @@ public boolean onLoadFailed( iconBackground.setBackgroundColor(grey_color); new Handler( msg -> { - GlideApp.with(mainFragment) + Glide.with(mainFragment) .load(R.drawable.ic_broken_image_white_24dp) .into(viewHolder.genericIcon); return false; diff --git a/app/src/main/java/com/amaze/filemanager/adapters/glide/AppsAdapterPreloadModel.java b/app/src/main/java/com/amaze/filemanager/adapters/glide/AppsAdapterPreloadModel.java index c76d130cfc..0ee56e21bd 100644 --- a/app/src/main/java/com/amaze/filemanager/adapters/glide/AppsAdapterPreloadModel.java +++ b/app/src/main/java/com/amaze/filemanager/adapters/glide/AppsAdapterPreloadModel.java @@ -27,8 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.amaze.filemanager.GlideApp; -import com.amaze.filemanager.GlideRequest; +import com.bumptech.glide.Glide; import com.amaze.filemanager.R; import com.bumptech.glide.ListPreloader; import com.bumptech.glide.RequestBuilder; @@ -51,12 +50,12 @@ public class AppsAdapterPreloadModel implements ListPreloader.PreloadModelProvid private final Logger LOG = LoggerFactory.getLogger(AppsAdapterPreloadModel.class); private Context mContext; - private GlideRequest request; + private RequestBuilder request; private List items; private boolean isBottomSheet; public AppsAdapterPreloadModel(Fragment f, boolean isBottomSheet) { - request = GlideApp.with(f).asDrawable().fitCenter(); + request = Glide.with(f).asDrawable().fitCenter(); this.mContext = f.requireContext(); this.isBottomSheet = isBottomSheet; } diff --git a/app/src/main/java/com/amaze/filemanager/adapters/glide/RecyclerPreloadModelProvider.java b/app/src/main/java/com/amaze/filemanager/adapters/glide/RecyclerPreloadModelProvider.java index 706c65e883..6d108b36ce 100644 --- a/app/src/main/java/com/amaze/filemanager/adapters/glide/RecyclerPreloadModelProvider.java +++ b/app/src/main/java/com/amaze/filemanager/adapters/glide/RecyclerPreloadModelProvider.java @@ -23,8 +23,7 @@ import java.util.Collections; import java.util.List; -import com.amaze.filemanager.GlideApp; -import com.amaze.filemanager.GlideRequest; +import com.bumptech.glide.Glide; import com.amaze.filemanager.adapters.data.IconDataParcelable; import com.bumptech.glide.ListPreloader; import com.bumptech.glide.RequestBuilder; @@ -43,12 +42,12 @@ public class RecyclerPreloadModelProvider implements ListPreloader.PreloadModelProvider { private final List urisToLoad; - private final GlideRequest request; + private final RequestBuilder request; public RecyclerPreloadModelProvider( @NonNull Fragment fragment, @NonNull List uris, boolean isCircled) { urisToLoad = uris; - GlideRequest incompleteRequest = GlideApp.with(fragment).asDrawable(); + RequestBuilder incompleteRequest = Glide.with(fragment).asDrawable(); if (isCircled) { request = incompleteRequest.circleCrop(); diff --git a/app/src/main/java/com/amaze/filemanager/crashreport/ErrorActivity.java b/app/src/main/java/com/amaze/filemanager/crashreport/ErrorActivity.java index 7921a34c40..ecc4774038 100644 --- a/app/src/main/java/com/amaze/filemanager/crashreport/ErrorActivity.java +++ b/app/src/main/java/com/amaze/filemanager/crashreport/ErrorActivity.java @@ -264,19 +264,14 @@ public boolean onCreateOptionsMenu(final Menu menu) { @Override public boolean onOptionsItemSelected(final MenuItem item) { final int id = item.getItemId(); - switch (id) { - case android.R.id.home: - goToReturnActivity(); - break; - case R.id.menu_item_share_error: - final Intent intent = new Intent(); - intent.setAction(Intent.ACTION_SEND); - intent.putExtra(Intent.EXTRA_TEXT, buildMarkdown()); - intent.setType("text/plain"); - startActivity(Intent.createChooser(intent, getString(R.string.share))); - break; - default: - break; + if (id == android.R.id.home) { + goToReturnActivity(); + } else if (id == R.id.menu_item_share_error) { + final Intent intent = new Intent(); + intent.setAction(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_TEXT, buildMarkdown()); + intent.setType("text/plain"); + startActivity(Intent.createChooser(intent, getString(R.string.share))); } return false; } diff --git a/app/src/main/java/com/amaze/filemanager/ui/ItemPopupMenu.java b/app/src/main/java/com/amaze/filemanager/ui/ItemPopupMenu.java index 38ec94083e..4cd1a32136 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/ItemPopupMenu.java +++ b/app/src/main/java/com/amaze/filemanager/ui/ItemPopupMenu.java @@ -94,8 +94,8 @@ public ItemPopupMenu( @Override public boolean onMenuItemClick(MenuItem item) { - switch (item.getItemId()) { - case R.id.about: + int id = item.getItemId(); + if (id == R.id.about) { GeneralDialogCreation.showPropertiesDialogWithPermissions( (rowItem).generateBaseFile(), rowItem.permissions, @@ -104,7 +104,7 @@ public boolean onMenuItemClick(MenuItem item) { mainActivity.isRootExplorer(), utilitiesProvider.getAppTheme()); return true; - case R.id.share: + } else if (id == R.id.share) { switch (rowItem.getMode()) { case DROPBOX: case BOX: @@ -120,24 +120,21 @@ public boolean onMenuItemClick(MenuItem item) { break; } return true; - case R.id.rename: + } else if (id == R.id.rename) { mainFragment.rename(rowItem.generateBaseFile()); return true; - case R.id.cpy: - case R.id.cut: - { - int op = - item.getItemId() == R.id.cpy ? PasteHelper.OPERATION_COPY : PasteHelper.OPERATION_CUT; - PasteHelper pasteHelper = - new PasteHelper( - mainActivity, op, new HybridFileParcelable[] {rowItem.generateBaseFile()}); - mainActivity.setPaste(pasteHelper); - return true; - } - case R.id.ex: + } else if (id == R.id.cpy || id == R.id.cut) { + int op = + item.getItemId() == R.id.cpy ? PasteHelper.OPERATION_COPY : PasteHelper.OPERATION_CUT; + PasteHelper pasteHelper = + new PasteHelper( + mainActivity, op, new HybridFileParcelable[] {rowItem.generateBaseFile()}); + mainActivity.setPaste(pasteHelper); + return true; + } else if (id == R.id.ex) { mainActivity.mainActivityHelper.extractFile(new File(rowItem.desc)); return true; - case R.id.book: + } else if (id == R.id.book) { DataUtils dataUtils = DataUtils.getInstance(); if (dataUtils.addBook(new String[] {rowItem.title, rowItem.desc}, true)) { mainActivity.getDrawer().refreshDrawer(); @@ -154,19 +151,19 @@ public boolean onMenuItemClick(MenuItem item) { .show(); } return true; - case R.id.delete: + } else if (id == R.id.delete) { ArrayList positions = new ArrayList<>(); positions.add(rowItem); GeneralDialogCreation.deleteFilesDialog( context, mainActivity, positions, utilitiesProvider.getAppTheme()); return true; - case R.id.restore: + } else if (id == R.id.restore) { ArrayList p2 = new ArrayList<>(); p2.add(rowItem); GeneralDialogCreation.restoreFilesDialog( context, mainActivity, p2, utilitiesProvider.getAppTheme()); return true; - case R.id.open_with: + } else if (id == R.id.open_with) { boolean useNewStack = sharedPrefs.getBoolean(PreferencesConstants.PREFERENCE_TEXTEDITOR_NEWSTACK, false); @@ -188,7 +185,7 @@ public boolean onMenuItemClick(MenuItem item) { FileUtils.openWith(new File(rowItem.desc), mainActivity, useNewStack); return true; - case R.id.encrypt: + } else if (id == R.id.encrypt) { final Intent encryptIntent = new Intent(context, EncryptService.class); encryptIntent.putExtra(EncryptService.TAG_OPEN_MODE, rowItem.getMode().ordinal()); encryptIntent.putExtra(EncryptService.TAG_SOURCE, rowItem.generateBaseFile()); @@ -236,7 +233,7 @@ public void onButtonPressed(Intent intent, String password) encryptButtonCallbackInterfaceAuthenticate); } return true; - case R.id.decrypt: + } else if (id == R.id.decrypt) { EncryptDecryptUtils.decryptFile( context, mainActivity, @@ -247,13 +244,13 @@ public void onButtonPressed(Intent intent, String password) utilitiesProvider, false); return true; - case R.id.compress: + } else if (id == R.id.compress) { GeneralDialogCreation.showCompressDialog( mainActivity, rowItem.generateBaseFile(), mainActivity.getCurrentMainFragment().getMainFragmentViewModel().getCurrentPath()); return true; - case R.id.return_select: + } else if (id == R.id.return_select) { mainFragment.returnIntentResults(new HybridFileParcelable[] {rowItem.generateBaseFile()}); return true; } diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/AboutActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/AboutActivity.java index 93c5aa2d87..1359885727 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/AboutActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/AboutActivity.java @@ -37,6 +37,7 @@ import com.amaze.filemanager.utils.Billing; import com.amaze.filemanager.utils.PreferenceUtils; import com.amaze.filemanager.utils.Utils; +import androidx.core.content.ContextCompat; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; import com.mikepenz.aboutlibraries.Libs; @@ -116,7 +117,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { Toolbar mToolbar = findViewById(R.id.toolBar); setSupportActionBar(mToolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.md_nav_back)); + getSupportActionBar().setHomeAsUpIndicator(ContextCompat.getDrawable(this, android.R.drawable.ic_menu_revert)); getSupportActionBar().setDisplayShowTitleEnabled(false); switchIcons(); @@ -188,10 +189,9 @@ private CoordinatorLayout.LayoutParams calculateHeaderViewParams() { @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - onBackPressed(); - break; + int id = item.getItemId(); + if (id == android.R.id.home) { + onBackPressed(); } return super.onOptionsItemSelected(item); } @@ -208,100 +208,73 @@ private void switchIcons() { @Override public void onClick(View v) { - switch (v.getId()) { - case R.id.relative_layout_source: - openURL(URL_REPO, this); - break; - - case R.id.relative_layout_issues: - openURL(URL_REPO_ISSUES, this); - break; - - case R.id.relative_layout_share_logs: - try { - File logFile = - new File( - "/data/data/" + getApplicationContext().getPackageName() + "/cache/logs.txt"); - Uri logUri = - FileProvider.getUriForFile( - getApplicationContext(), getApplicationContext().getPackageName(), logFile); - ArrayList logUriList = new ArrayList<>(); - logUriList.add(logUri); - new ShareTask(this, logUriList, this.getAppTheme(), getAccent()).execute("*/*"); - } catch (Exception e) { - LOG.warn("failed to share logs", e); - } - break; - - case R.id.relative_layout_changelog: - openURL(URL_REPO_CHANGELOG, this); - break; - - case R.id.relative_layout_licenses: - LibsBuilder libsBuilder = - new LibsBuilder() - .withLibraries("apachemina") // Not auto-detected for some reason - .withActivityTitle(getString(R.string.libraries)) - .withAboutIconShown(true) - .withAboutVersionShownName(true) - .withAboutVersionShownCode(false) - .withAboutDescription(getString(R.string.about_amaze)) - .withAboutSpecial1(getString(R.string.license)) - .withAboutSpecial1Description(getString(R.string.amaze_license)) - .withLicenseShown(true); - - switch (getAppTheme()) { - case LIGHT: - libsBuilder.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR); - break; - case DARK: - libsBuilder.withActivityStyle(Libs.ActivityStyle.DARK); - break; - case BLACK: - libsBuilder.withActivityTheme(R.style.AboutLibrariesTheme_Black); - break; - default: - LogHelper.logOnProductionOrCrash("Incorrect value for switch"); - } - - libsBuilder.start(this); - - break; - - case R.id.text_view_author_1_github: - openURL(URL_AUTHOR1_GITHUB, this); - break; - - case R.id.text_view_author_2_github: - openURL(URL_AUTHOR2_GITHUB, this); - break; - - case R.id.text_view_developer_1_github: - openURL(URL_DEVELOPER1_GITHUB, this); - break; - - case R.id.text_view_developer_2_github: - openURL(URL_DEVELOPER2_GITHUB, this); - break; - - case R.id.text_view_developer_3_github: - openURL(URL_DEVELOPER3_GITHUB, this); - break; - - case R.id.relative_layout_translate: - openURL(URL_REPO_TRANSLATE, this); - break; - - case R.id.relative_layout_xda: - openURL(URL_REPO_XDA, this); - break; + int id = v.getId(); + if (id == R.id.relative_layout_source) { + openURL(URL_REPO, this); + } else if (id == R.id.relative_layout_issues) { + openURL(URL_REPO_ISSUES, this); + } else if (id == R.id.relative_layout_share_logs) { + try { + File logFile = + new File( + "/data/data/" + getApplicationContext().getPackageName() + "/cache/logs.txt"); + Uri logUri = + FileProvider.getUriForFile( + getApplicationContext(), getApplicationContext().getPackageName(), logFile); + ArrayList logUriList = new ArrayList<>(); + logUriList.add(logUri); + new ShareTask(this, logUriList, this.getAppTheme(), getAccent()).execute("*/*"); + } catch (Exception e) { + LOG.warn("failed to share logs", e); + } + } else if (id == R.id.relative_layout_changelog) { + openURL(URL_REPO_CHANGELOG, this); + } else if (id == R.id.relative_layout_licenses) { + LibsBuilder libsBuilder = + new LibsBuilder() + .withLibraries("apachemina") // Not auto-detected for some reason + .withActivityTitle(getString(R.string.libraries)) + .withAboutIconShown(true) + .withAboutVersionShownName(true) + .withAboutVersionShownCode(false) + .withAboutDescription(getString(R.string.about_amaze)) + .withAboutSpecial1(getString(R.string.license)) + .withAboutSpecial1Description(getString(R.string.amaze_license)) + .withLicenseShown(true); + + switch (getAppTheme()) { + case LIGHT: + libsBuilder.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR); + break; + case DARK: + libsBuilder.withActivityStyle(Libs.ActivityStyle.DARK); + break; + case BLACK: + libsBuilder.withActivityTheme(R.style.AboutLibrariesTheme_Black); + break; + default: + LogHelper.logOnProductionOrCrash("Incorrect value for switch"); + } - case R.id.relative_layout_rate: - openURL(URL_REPO_RATE, this); - break; - case R.id.relative_layout_donate: - billing = new Billing(this); - break; + libsBuilder.start(this); + } else if (id == R.id.text_view_author_1_github) { + openURL(URL_AUTHOR1_GITHUB, this); + } else if (id == R.id.text_view_author_2_github) { + openURL(URL_AUTHOR2_GITHUB, this); + } else if (id == R.id.text_view_developer_1_github) { + openURL(URL_DEVELOPER1_GITHUB, this); + } else if (id == R.id.text_view_developer_2_github) { + openURL(URL_DEVELOPER2_GITHUB, this); + } else if (id == R.id.text_view_developer_3_github) { + openURL(URL_DEVELOPER3_GITHUB, this); + } else if (id == R.id.relative_layout_translate) { + openURL(URL_REPO_TRANSLATE, this); + } else if (id == R.id.relative_layout_xda) { + openURL(URL_REPO_XDA, this); + } else if (id == R.id.relative_layout_rate) { + openURL(URL_REPO_RATE, this); + } else if (id == R.id.relative_layout_donate) { + billing = new Billing(this); } } 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 ff894315c9..b77de71954 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 @@ -1168,19 +1168,16 @@ public boolean onOptionsItemSelected(MenuItem item) { // Handle action buttons executeWithMainFragment( mainFragment -> { - switch (item.getItemId()) { - case R.id.home: - mainFragment.home(); - break; - case R.id.history: - HistoryDialog.showHistoryDialog(this, mainFragment); - break; - case R.id.sethome: - if (mainFragment.getMainFragmentViewModel().getOpenMode() != OpenMode.FILE - && mainFragment.getMainFragmentViewModel().getOpenMode() != OpenMode.ROOT) { - Toast.makeText(mainActivity, R.string.not_allowed, Toast.LENGTH_SHORT).show(); - break; - } + int id = item.getItemId(); + if (id == R.id.home) { + mainFragment.home(); + } else if (id == R.id.history) { + HistoryDialog.showHistoryDialog(this, mainFragment); + } else if (id == R.id.sethome) { + if (mainFragment.getMainFragmentViewModel().getOpenMode() != OpenMode.FILE + && mainFragment.getMainFragmentViewModel().getOpenMode() != OpenMode.ROOT) { + Toast.makeText(mainActivity, R.string.not_allowed, Toast.LENGTH_SHORT).show(); + } else { final MaterialDialog dialog = GeneralDialogCreation.showBasicDialog( mainActivity, @@ -1199,93 +1196,86 @@ public boolean onOptionsItemSelected(MenuItem item) { dialog.dismiss(); }); dialog.show(); - break; - case R.id.exit: - finish(); - break; - case R.id.sortby: - GeneralDialogCreation.showSortDialog(mainFragment, getAppTheme(), getPrefs()); - break; - case R.id.dsort: - String[] sort = getResources().getStringArray(R.array.directorysortmode); - MaterialDialog.Builder builder = new MaterialDialog.Builder(mainActivity); - builder.theme(getAppTheme().getMaterialDialogTheme()); - builder.title(R.string.directorysort); - int current = - Integer.parseInt( + } + } else if (id == R.id.exit) { + finish(); + } else if (id == R.id.sortby) { + GeneralDialogCreation.showSortDialog(mainFragment, getAppTheme(), getPrefs()); + } else if (id == R.id.dsort) { + String[] sort = getResources().getStringArray(R.array.directorysortmode); + MaterialDialog.Builder builder = new MaterialDialog.Builder(mainActivity); + builder.theme(getAppTheme().getMaterialDialogTheme()); + builder.title(R.string.directorysort); + int current = + Integer.parseInt( + getPrefs() + .getString(PreferencesConstants.PREFERENCE_DIRECTORY_SORT_MODE, "0")); + + builder + .items(sort) + .itemsCallbackSingleChoice( + current, + (dialog1, view, which, text) -> { getPrefs() - .getString(PreferencesConstants.PREFERENCE_DIRECTORY_SORT_MODE, "0")); - - builder - .items(sort) - .itemsCallbackSingleChoice( - current, - (dialog1, view, which, text) -> { - getPrefs() - .edit() - .putString( - PreferencesConstants.PREFERENCE_DIRECTORY_SORT_MODE, "" + which) - .commit(); - mainFragment - .getMainFragmentViewModel() - .initSortModes( - SortHandler.getSortType( - this, mainFragment.getMainFragmentViewModel().getCurrentPath()), - getPrefs()); - mainFragment.updateList(false); - dialog1.dismiss(); - return true; - }); - builder.build().show(); - break; - case R.id.hiddenitems: - HiddenFilesDialog.showHiddenDialog(this, mainFragment); - break; - case R.id.view: - int pathLayout = - dataUtils.getListOrGridForPath(mainFragment.getCurrentPath(), DataUtils.LIST); - if (mainFragment.getMainFragmentViewModel().isList()) { - if (pathLayout == DataUtils.LIST) { - AppConfig.getInstance() - .runInBackground( - () -> { - utilsHandler.removeFromDatabase( - new OperationData( - UtilsHandler.Operation.LIST, mainFragment.getCurrentPath())); - }); - } - utilsHandler.saveToDatabase( - new OperationData(UtilsHandler.Operation.GRID, mainFragment.getCurrentPath())); + .edit() + .putString( + PreferencesConstants.PREFERENCE_DIRECTORY_SORT_MODE, "" + which) + .commit(); + mainFragment + .getMainFragmentViewModel() + .initSortModes( + SortHandler.getSortType( + this, mainFragment.getMainFragmentViewModel().getCurrentPath()), + getPrefs()); + mainFragment.updateList(false); + dialog1.dismiss(); + return true; + }); + builder.build().show(); + } else if (id == R.id.hiddenitems) { + HiddenFilesDialog.showHiddenDialog(this, mainFragment); + } else if (id == R.id.view) { + int pathLayout = + dataUtils.getListOrGridForPath(mainFragment.getCurrentPath(), DataUtils.LIST); + if (mainFragment.getMainFragmentViewModel().isList()) { + if (pathLayout == DataUtils.LIST) { + AppConfig.getInstance() + .runInBackground( + () -> { + utilsHandler.removeFromDatabase( + new OperationData( + UtilsHandler.Operation.LIST, mainFragment.getCurrentPath())); + }); + } + utilsHandler.saveToDatabase( + new OperationData(UtilsHandler.Operation.GRID, mainFragment.getCurrentPath())); - dataUtils.setPathAsGridOrList(mainFragment.getCurrentPath(), DataUtils.GRID); - } else { - if (pathLayout == DataUtils.GRID) { - AppConfig.getInstance() - .runInBackground( - () -> { - utilsHandler.removeFromDatabase( - new OperationData( - UtilsHandler.Operation.GRID, mainFragment.getCurrentPath())); - }); - } + dataUtils.setPathAsGridOrList(mainFragment.getCurrentPath(), DataUtils.GRID); + } else { + if (pathLayout == DataUtils.GRID) { + AppConfig.getInstance() + .runInBackground( + () -> { + utilsHandler.removeFromDatabase( + new OperationData( + UtilsHandler.Operation.GRID, mainFragment.getCurrentPath())); + }); + } - utilsHandler.saveToDatabase( - new OperationData(UtilsHandler.Operation.LIST, mainFragment.getCurrentPath())); + utilsHandler.saveToDatabase( + new OperationData(UtilsHandler.Operation.LIST, mainFragment.getCurrentPath())); - dataUtils.setPathAsGridOrList(mainFragment.getCurrentPath(), DataUtils.LIST); - } - mainFragment.switchView(); - break; - case R.id.extract: - Fragment fragment1 = getFragmentAtFrame(); - if (fragment1 instanceof CompressedExplorerFragment) { - mainActivityHelper.extractFile( - ((CompressedExplorerFragment) fragment1).compressedFile); - } - break; - case R.id.search: - getAppbar().getSearchView().revealSearchView(); - break; + dataUtils.setPathAsGridOrList(mainFragment.getCurrentPath(), DataUtils.LIST); + } + mainFragment.switchView(); + } else if (id == R.id.extract) { + Fragment fragment1 = getFragmentAtFrame(); + if (fragment1 instanceof CompressedExplorerFragment) { + mainActivityHelper.extractFile( + ((CompressedExplorerFragment) fragment1).compressedFile); + } + } else if (id == R.id.search) { + getAppbar().getSearchView().revealSearchView(); } return null; }, diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/texteditor/TextEditorActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/texteditor/TextEditorActivity.java index 471661dea2..5d25cedccb 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/texteditor/TextEditorActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/texteditor/TextEditorActivity.java @@ -293,58 +293,52 @@ public boolean onOptionsItemSelected(MenuItem item) { new ViewModelProvider(this).get(TextEditorActivityViewModel.class); final EditableFileAbstraction editableFileAbstraction = viewModel.getFile(); - switch (item.getItemId()) { - case android.R.id.home: - checkUnsavedChanges(); - break; - case R.id.save: - // Make sure EditText is visible before saving! - if (mainTextView.getText() != null) { - saveFile(this, mainTextView.getText().toString()); - } - break; - case R.id.details: - if (editableFileAbstraction.scheme.equals(FILE) - && editableFileAbstraction.hybridFileParcelable.getFile() != null - && editableFileAbstraction.hybridFileParcelable.getFile().exists()) { - GeneralDialogCreation.showPropertiesDialogWithoutPermissions( - editableFileAbstraction.hybridFileParcelable, this, getAppTheme()); - } else if (editableFileAbstraction.scheme.equals(CONTENT)) { - if (getApplicationContext() - .getPackageName() - .equals(editableFileAbstraction.uri.getAuthority())) { - File file = FileUtils.fromContentUri(editableFileAbstraction.uri); - HybridFileParcelable p = new HybridFileParcelable(file.getAbsolutePath()); - if (isRootExplorer()) p.setMode(OpenMode.ROOT); - GeneralDialogCreation.showPropertiesDialogWithoutPermissions(p, this, getAppTheme()); - } - } else { - Toast.makeText(this, R.string.no_obtainable_info, Toast.LENGTH_SHORT).show(); + int id = item.getItemId(); + if (id == android.R.id.home) { + checkUnsavedChanges(); + } else if (id == R.id.save) { + // Make sure EditText is visible before saving! + if (mainTextView.getText() != null) { + saveFile(this, mainTextView.getText().toString()); + } + } else if (id == R.id.details) { + if (editableFileAbstraction.scheme.equals(FILE) + && editableFileAbstraction.hybridFileParcelable.getFile() != null + && editableFileAbstraction.hybridFileParcelable.getFile().exists()) { + GeneralDialogCreation.showPropertiesDialogWithoutPermissions( + editableFileAbstraction.hybridFileParcelable, this, getAppTheme()); + } else if (editableFileAbstraction.scheme.equals(CONTENT)) { + if (getApplicationContext() + .getPackageName() + .equals(editableFileAbstraction.uri.getAuthority())) { + File file = FileUtils.fromContentUri(editableFileAbstraction.uri); + HybridFileParcelable p = new HybridFileParcelable(file.getAbsolutePath()); + if (isRootExplorer()) p.setMode(OpenMode.ROOT); + GeneralDialogCreation.showPropertiesDialogWithoutPermissions(p, this, getAppTheme()); } - break; - case R.id.openwith: - if (editableFileAbstraction.scheme.equals(FILE)) { - File currentFile = editableFileAbstraction.hybridFileParcelable.getFile(); - if (currentFile != null && currentFile.exists()) { - boolean useNewStack = getBoolean(PREFERENCE_TEXTEDITOR_NEWSTACK); - FileUtils.openWith(currentFile, this, useNewStack); - } else { - Toast.makeText(this, R.string.not_allowed, Toast.LENGTH_SHORT).show(); - } + } else { + Toast.makeText(this, R.string.no_obtainable_info, Toast.LENGTH_SHORT).show(); + } + } else if (id == R.id.openwith) { + if (editableFileAbstraction.scheme.equals(FILE)) { + File currentFile = editableFileAbstraction.hybridFileParcelable.getFile(); + if (currentFile != null && currentFile.exists()) { + boolean useNewStack = getBoolean(PREFERENCE_TEXTEDITOR_NEWSTACK); + FileUtils.openWith(currentFile, this, useNewStack); } else { - Toast.makeText(this, R.string.reopen_from_source, Toast.LENGTH_SHORT).show(); + Toast.makeText(this, R.string.not_allowed, Toast.LENGTH_SHORT).show(); } - break; - case R.id.find: - if (searchViewLayout.isShown()) hideSearchView(); - else revealSearchView(); - break; - case R.id.monofont: - item.setChecked(!item.isChecked()); - mainTextView.setTypeface(item.isChecked() ? inputTypefaceMono : inputTypefaceDefault); - break; - default: - return false; + } else { + Toast.makeText(this, R.string.reopen_from_source, Toast.LENGTH_SHORT).show(); + } + } else if (id == R.id.find) { + if (searchViewLayout.isShown()) hideSearchView(); + else revealSearchView(); + } else if (id == R.id.monofont) { + item.setChecked(!item.isChecked()); + mainTextView.setTypeface(item.isChecked() ? inputTypefaceMono : inputTypefaceDefault); + } else { + return false; } return super.onOptionsItemSelected(item); } @@ -546,19 +540,18 @@ public void onClick(View v) { final TextEditorActivityViewModel viewModel = new ViewModelProvider(this).get(TextEditorActivityViewModel.class); - switch (v.getId()) { - case R.id.textEditorSearchPrevButton: - // upButton - if (viewModel.getCurrent() > 0) { - unhighlightCurrentSearchResult(viewModel); + int id = v.getId(); + if (id == R.id.textEditorSearchPrevButton) { + // upButton + if (viewModel.getCurrent() > 0) { + unhighlightCurrentSearchResult(viewModel); - // highlighting previous element in list - viewModel.setCurrent(viewModel.getCurrent() - 1); + // highlighting previous element in list + viewModel.setCurrent(viewModel.getCurrent() - 1); - highlightCurrentSearchResult(viewModel); - } - break; - case R.id.textEditorSearchNextButton: + highlightCurrentSearchResult(viewModel); + } + } else if (id == R.id.textEditorSearchNextButton) { // downButton if (viewModel.getCurrent() < viewModel.getSearchResultIndices().size() - 1) { unhighlightCurrentSearchResult(viewModel); @@ -567,9 +560,6 @@ public void onClick(View v) { highlightCurrentSearchResult(viewModel); } - break; - default: - throw new IllegalStateException(); } } diff --git a/app/src/main/java/com/amaze/filemanager/ui/dialogs/OpenFileDialogFragment.kt b/app/src/main/java/com/amaze/filemanager/ui/dialogs/OpenFileDialogFragment.kt index e0b5746617..4a168b46d6 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/dialogs/OpenFileDialogFragment.kt +++ b/app/src/main/java/com/amaze/filemanager/ui/dialogs/OpenFileDialogFragment.kt @@ -34,7 +34,7 @@ import android.view.ViewGroup import android.widget.Toast import androidx.preference.PreferenceManager import androidx.recyclerview.widget.LinearLayoutManager -import com.amaze.filemanager.GlideApp +import com.bumptech.glide.Glide import com.amaze.filemanager.R import com.amaze.filemanager.adapters.AppsRecyclerAdapter import com.amaze.filemanager.adapters.data.AppDataParcelable @@ -311,7 +311,7 @@ class OpenFileDialogFragment : BaseBottomSheetFragment(), AdjustListViewForTv() var preloader = RecyclerViewPreloader( - GlideApp.with(this), + Glide.with(this), modelProvider, sizeProvider, GlideConstants.MAX_PRELOAD_FILES diff --git a/app/src/main/java/com/amaze/filemanager/ui/fragments/AppsListFragment.java b/app/src/main/java/com/amaze/filemanager/ui/fragments/AppsListFragment.java index da887dc805..ecc95d4f01 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/fragments/AppsListFragment.java +++ b/app/src/main/java/com/amaze/filemanager/ui/fragments/AppsListFragment.java @@ -30,7 +30,7 @@ import java.util.Objects; import com.afollestad.materialdialogs.MaterialDialog; -import com.amaze.filemanager.GlideApp; +import com.bumptech.glide.Glide; import com.amaze.filemanager.R; import com.amaze.filemanager.adapters.AppsRecyclerAdapter; import com.amaze.filemanager.adapters.data.AppDataParcelable; @@ -113,7 +113,7 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { ViewPreloadSizeProvider sizeProvider = new ViewPreloadSizeProvider<>(); preloader = new RecyclerViewPreloader<>( - GlideApp.with(this), + Glide.with(this), modelProvider, sizeProvider, GlideConstants.MAX_PRELOAD_APPSADAPTER); @@ -145,20 +145,20 @@ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflat @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.sort: - showSortDialog(((MainActivity) requireActivity()).getAppTheme()); - return true; - case R.id.exit: - requireActivity().finish(); - return true; - case R.id.checkbox_system_apps: - item.setChecked(!item.isChecked()); - adapter.setData(appDataParcelableList, item.isChecked()); - showSystemApps = item.isChecked(); - return true; - default: - return super.onOptionsItemSelected(item); + int id = item.getItemId(); + if (id == R.id.sort) { + showSortDialog(((MainActivity) requireActivity()).getAppTheme()); + return true; + } else if (id == R.id.exit) { + requireActivity().finish(); + return true; + } else if (id == R.id.checkbox_system_apps) { + item.setChecked(!item.isChecked()); + adapter.setData(appDataParcelableList, item.isChecked()); + showSystemApps = item.isChecked(); + return true; + } else { + return super.onOptionsItemSelected(item); } } diff --git a/app/src/main/java/com/amaze/filemanager/ui/fragments/CloudSheetFragment.java b/app/src/main/java/com/amaze/filemanager/ui/fragments/CloudSheetFragment.java index 0037e97a49..bdd7d17e43 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/fragments/CloudSheetFragment.java +++ b/app/src/main/java/com/amaze/filemanager/ui/fragments/CloudSheetFragment.java @@ -155,33 +155,29 @@ public static final boolean isCloudProviderAvailable(Context context) { @Override public void onClick(View v) { - switch (v.getId()) { - case R.id.linear_layout_smb: - dismiss(); - SmbSearchDialog smbDialog = new SmbSearchDialog(); - smbDialog.show(getActivity().getSupportFragmentManager(), "tab"); - return; - case R.id.linear_layout_scp: - dismiss(); - SftpConnectDialog sftpConnectDialog = new SftpConnectDialog(); - Bundle args = new Bundle(); - args.putBoolean("edit", false); - sftpConnectDialog.setArguments(args); - sftpConnectDialog.show(getFragmentManager(), "tab"); - return; - case R.id.linear_layout_box: - ((MainActivity) getActivity()).addConnection(OpenMode.BOX); - break; - case R.id.linear_layout_dropbox: - ((MainActivity) getActivity()).addConnection(OpenMode.DROPBOX); - break; - case R.id.linear_layout_google_drive: - GeneralDialogCreation.showSignInWithGoogleDialog((MainActivity) getActivity()); - break; - case R.id.linear_layout_onedrive: - ((MainActivity) getActivity()).addConnection(OpenMode.ONEDRIVE); - break; - case R.id.linear_layout_get_cloud: + int id = v.getId(); + if (id == R.id.linear_layout_smb) { + dismiss(); + SmbSearchDialog smbDialog = new SmbSearchDialog(); + smbDialog.show(getActivity().getSupportFragmentManager(), "tab"); + return; + } else if (id == R.id.linear_layout_scp) { + dismiss(); + SftpConnectDialog sftpConnectDialog = new SftpConnectDialog(); + Bundle args = new Bundle(); + args.putBoolean("edit", false); + sftpConnectDialog.setArguments(args); + sftpConnectDialog.show(getFragmentManager(), "tab"); + return; + } else if (id == R.id.linear_layout_box) { + ((MainActivity) getActivity()).addConnection(OpenMode.BOX); + } else if (id == R.id.linear_layout_dropbox) { + ((MainActivity) getActivity()).addConnection(OpenMode.DROPBOX); + } else if (id == R.id.linear_layout_google_drive) { + GeneralDialogCreation.showSignInWithGoogleDialog((MainActivity) getActivity()); + } else if (id == R.id.linear_layout_onedrive) { + ((MainActivity) getActivity()).addConnection(OpenMode.ONEDRIVE); + } else if (id == R.id.linear_layout_get_cloud) { Intent cloudPluginIntent = new Intent(Intent.ACTION_VIEW); cloudPluginIntent.setData(Uri.parse(getString(R.string.cloud_plugin_google_play_uri))); try { @@ -191,7 +187,6 @@ public void onClick(View v) { Uri.parse(getString(R.string.cloud_plugin_google_play_web_uri))); startActivity(cloudPluginIntent); } - break; } // dismiss this sheet dialog diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/FastScroller.java b/app/src/main/java/com/amaze/filemanager/ui/views/FastScroller.java index 2f89d1a683..c474bd3e5b 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/FastScroller.java +++ b/app/src/main/java/com/amaze/filemanager/ui/views/FastScroller.java @@ -111,7 +111,7 @@ private void setHandlePosition1(float relativePos) { private void setUpBarBackground() { InsetDrawable insetDrawable; - int resolveColor = resolveColor(getContext(), R.attr.colorControlNormal); + int resolveColor = resolveColor(getContext(), android.R.attr.textColorSecondary); insetDrawable = new InsetDrawable( new ColorDrawable(resolveColor), diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/ScrimInsetsRelativeLayout.java b/app/src/main/java/com/amaze/filemanager/ui/views/ScrimInsetsRelativeLayout.java index 864f1d0a20..ca6e20f010 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/ScrimInsetsRelativeLayout.java +++ b/app/src/main/java/com/amaze/filemanager/ui/views/ScrimInsetsRelativeLayout.java @@ -59,13 +59,21 @@ public ScrimInsetsRelativeLayout(Context context, AttributeSet attrs, int defSty } private void init(Context context, AttributeSet attrs, int defStyle) { - final TypedArray a = - context.obtainStyledAttributes(attrs, R.styleable.ScrimInsetsFrameLayout, defStyle, 0); - if (a == null) { - return; + // Note: ScrimInsetsFrameLayout styleable may not exist, handle gracefully + TypedArray a = null; + try { + a = context.obtainStyledAttributes(attrs, R.styleable.ScrimInsetsFrameLayout, defStyle, 0); + if (a != null) { + mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsFrameLayout_insetForeground); + } + } catch (Exception e) { + // Styleable doesn't exist, use null (will be handled in draw method) + mInsetForeground = null; + } finally { + if (a != null) { + a.recycle(); + } } - mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsFrameLayout_insetForeground); - a.recycle(); setWillNotDraw(true); } diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/appbar/SearchView.java b/app/src/main/java/com/amaze/filemanager/ui/views/appbar/SearchView.java index 126779a069..8fdd6022a0 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/appbar/SearchView.java +++ b/app/src/main/java/com/amaze/filemanager/ui/views/appbar/SearchView.java @@ -510,7 +510,7 @@ private void setSearchResultSortOrderIcon() { orderDrawable.setColorFilter( new PorterDuffColorFilter( - mainActivity.getResources().getColor(R.color.accent_material_light), + mainActivity.getAccent(), PorterDuff.Mode.SRC_ATOP)); searchResultsSortButton.setCompoundDrawablesWithIntrinsicBounds( null, null, orderDrawable, null); diff --git a/app/src/main/java/com/amaze/filemanager/utils/AnimUtils.kt b/app/src/main/java/com/amaze/filemanager/utils/AnimUtils.kt index 812b92dcc3..5e2b93be0f 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/AnimUtils.kt +++ b/app/src/main/java/com/amaze/filemanager/utils/AnimUtils.kt @@ -33,9 +33,11 @@ object AnimUtils { @JvmStatic fun getFastOutSlowInInterpolator(context: Context?): Interpolator? { + if (context == null) return null if (fastOutSlowIn == null) { fastOutSlowIn = - AnimationUtils.loadInterpolator(context, R.interpolator.fast_out_slow_in) + // Use the framework interpolator to avoid relying on a removed/renamed app resource. + AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in) } return fastOutSlowIn } diff --git a/app/src/main/java/com/amaze/filemanager/utils/Utils.java b/app/src/main/java/com/amaze/filemanager/utils/Utils.java index bc50b16de3..149cf0aa0e 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/Utils.java +++ b/app/src/main/java/com/amaze/filemanager/utils/Utils.java @@ -128,7 +128,7 @@ public static void setTint(Context context, AppCompatCheckBox box, int color) { } else { Drawable drawable = DrawableCompat.wrap( - ContextCompat.getDrawable(box.getContext(), R.drawable.abc_btn_check_material)); + ContextCompat.getDrawable(box.getContext(), android.R.drawable.checkbox_on_background)); DrawableCompat.setTintList(drawable, sl); box.setButtonDrawable(drawable); } diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index bb1bca1696..df9069122d 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -31,4 +31,8 @@ + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 515dc45fe0..893efab0b8 100644 --- a/build.gradle +++ b/build.gradle @@ -2,17 +2,19 @@ buildscript { ext { - kotlin_version = "1.8.0" + // Kotlin version compatible with AGP 8.5.x + kotlin_version = "1.9.24" robolectricVersion = '4.9' - glideVersion = '4.11.0' + glideVersion = '4.16.0' // Upgraded to support KSP (4.12.0+) sshjVersion = '0.35.0' jcifsVersion = '2.1.9' - fabSpeedDialVersion = '3.1.1' + // com.leinardi.android:speed-dial (3.1.1 no longer published on MavenCentral) + fabSpeedDialVersion = '3.3.0' roomVersion = '2.5.0' bouncyCastleVersion = '1.70' awaitilityVersion = "3.1.6" androidXCoreVersion = "1.7.0" - androidMaterialVersion = "1.5.0" // Upgrade to 1.5 requires targetSdkVersion 31 + androidMaterialVersion = "1.5.0" androidXFragmentVersion = "1.5.6" androidXAppCompatVersion = "1.6.1" androidXAnnotationVersion = "1.5.0" @@ -45,19 +47,19 @@ buildscript { rxJavaVersion = "2.2.9" okHttpVersion = "4.9.0" } + repositories { google() - maven { - url "https://plugins.gradle.org/m2/" - } + maven { url "https://plugins.gradle.org/m2/" } } + dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' - classpath 'com.hiya:jacoco-android:0.2' + // Keep AGP compatible with Android Studio + Gradle 8.5 + classpath 'com.android.tools.build:gradle:8.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.project.starter:easylauncher:6.1.0" - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + // KSP (Kotlin Symbol Processing) - faster alternative to KAPT, avoids Windows native library issues + classpath "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:1.9.24-1.0.20" } } @@ -72,30 +74,38 @@ allprojects { maven { url "https://jitpack.io" } maven { url "https://jcenter.bintray.com" } } - tasks.withType(Test).tap { - configureEach { - maxParallelForks = 8 - maxHeapSize = "2g" - forkEvery = 4 - failFast = true - } + + tasks.withType(Test).configureEach { + maxParallelForks = 8 + maxHeapSize = "2g" + forkEvery = 4 + failFast = true } } spotless { java { licenseHeaderFile 'spotless.license-java' - target 'app/src/**/*.java', 'commons_compress_7z/src/**/*.java', 'file_operations/src/**/*.java', 'portscanner/src/**/*.java' + target 'app/src/**/*.java', + 'commons_compress_7z/src/**/*.java', + 'file_operations/src/**/*.java', + 'portscanner/src/**/*.java' googleJavaFormat('1.15.0') - removeUnusedImports() // removes any unused imports + removeUnusedImports() importOrder 'java', 'javax', 'org', 'com', 'android', 'androidx', '' } + kotlin { licenseHeaderFile 'spotless.license-java' target 'app/src/**/*.kt', 'file_operations/src/**/*.kt' - ktlint("0.44.0").setUseExperimental(true).userData(['disabled_rules': 'no-wildcard-imports', - 'kotlin_imports_layout': 'idea', 'indent_size': '4', - 'max_line_length': '100']) + ktlint("0.44.0") + .setUseExperimental(true) + .userData([ + 'disabled_rules': 'no-wildcard-imports', + 'kotlin_imports_layout': 'idea', + 'indent_size': '4', + 'max_line_length': '100' + ]) trimTrailingWhitespace() indentWithSpaces() endWithNewline() @@ -166,41 +176,28 @@ tasks.register('fetchRobolectricDependencies', Copy) { } subprojects { - afterEvaluate { - if (project.plugins.hasPlugin("com.android.application") || project.plugins.hasPlugin("com.android.library")) { - android { + afterEvaluate { project -> + if (project.plugins.hasPlugin("com.android.application") + || project.plugins.hasPlugin("com.android.library")) { + + project.android { testOptions.unitTests.all { systemProperty 'robolectric.offline', 'true' systemProperty 'robolectric.dependency.dir', robolectricDependencies } } - tasks.withType(Test).configureEach { - it.dependsOn fetchRobolectricDependencies + project.tasks.withType(Test).configureEach { + dependsOn rootProject.tasks.fetchRobolectricDependencies } } - if (project.plugins.hasPlugin("jacoco-android")){ - android { - testOptions.unitTests.all { - jacoco { - excludes = ['jdk.internal.*'] - } - } - } - } - dependencies { - compileOnly 'com.github.pengrad:jdk9-deps:1.0' - - if (project.hasProperty('kapt')) { - kapt 'javax.xml.bind:jaxb-api:2.3.1' - kapt 'com.sun.xml.bind:jaxb-core:2.3.0.1' - kapt 'com.sun.xml.bind:jaxb-impl:2.3.2' - } + project.dependencies { + // NOTE: Previously we added `com.github.pengrad:jdk9-deps`, but it is not resolvable from our + // repositories and is not required for building on modern JDKs (17+). annotationProcessor 'javax.xml.bind:jaxb-api:2.3.1' annotationProcessor 'com.sun.xml.bind:jaxb-core:2.3.0.1' annotationProcessor 'com.sun.xml.bind:jaxb-impl:2.3.2' } } - } diff --git a/commons_compress_7z/build.gradle b/commons_compress_7z/build.gradle index 964762e8ba..13606745db 100644 --- a/commons_compress_7z/build.gradle +++ b/commons_compress_7z/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { + namespace "com.amaze.filemanager.filesystem.compressed.sevenz" compileSdk 33 defaultConfig { diff --git a/file_operations/build.gradle b/file_operations/build.gradle index 8f914de7b1..c637a2e3f2 100644 --- a/file_operations/build.gradle +++ b/file_operations/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { + namespace "com.amaze.filemanager.fileoperations" compileSdk 33 defaultConfig { @@ -32,8 +33,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } testOptions { @@ -46,17 +47,17 @@ android { externalNativeBuild { cmake { path file('src/main/c/CMakeLists.txt') - version '3.18.1' + // Don't pin a specific CMake version; use whatever is installed in the Android SDK. } } kotlinOptions { - jvmTarget = '11' + jvmTarget = '17' } } kotlin { - jvmToolchain(11) + jvmToolchain(17) } dependencies { diff --git a/gradle.properties b/gradle.properties index e9994ab628..ea62b60637 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,6 +19,12 @@ org.gradle.jvmargs=-Xmx4608M -XX:+UseParallelGC \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +# Android Studio may use a newer bundled JDK (e.g., Java 21) to run Gradle. +# This project uses Gradle 7.4.2, which requires running on Java <= 17. +# Point Gradle explicitly to a Java 17 install directory on Windows. +org.gradle.java.home=C:\\Program Files\\Java\\jdk-17 + + # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects @@ -26,5 +32,8 @@ org.gradle.parallel=true # https://github.com/usefulness/easylauncher-gradle-plugin/issues/408 android.disableResourceValidation=true +# Newer NDKs don't support API < 21; this project still targets minSdk 19. +# Suppress the NDK minSdk check so the project can configure/build. +android.ndk.suppressMinSdkVersionError=21 # for macs, omit for other operating systems # org.gradle.java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bbb86c79cb..44cfc615e2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat May 22 22:20:14 ART 2021 +#Wed Dec 17 22:46:17 IST 2025 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/portscanner/build.gradle b/portscanner/build.gradle index db62d06d39..3efc3f1a44 100644 --- a/portscanner/build.gradle +++ b/portscanner/build.gradle @@ -22,13 +22,13 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } } kotlin { - jvmToolchain(11) + jvmToolchain(17) } dependencies {