From 947cb5cb329b5cfb6bc7691e93a1c6248cf9af49 Mon Sep 17 00:00:00 2001 From: Hazman Date: Tue, 29 Oct 2024 15:31:30 +0800 Subject: [PATCH] Support Android 15. Java 17 --- app/build.gradle | 54 ++-- app/src/main/AndroidManifest.xml | 12 +- .../java/vi/filepicker/CallerFragment.java | 295 ++++++++---------- .../java/vi/filepicker/FragmentActivity.java | 4 +- .../main/java/vi/filepicker/ImageAdapter.java | 18 +- .../main/java/vi/filepicker/MainActivity.java | 47 +-- build.gradle | 20 +- filepicker/build.gradle | 134 ++------ filepicker/src/main/AndroidManifest.xml | 3 +- .../filepicker/FilePickerActivity.kt | 29 +- .../droidninja/filepicker/FilePickerConst.kt | 2 +- .../filepicker/MediaDetailsActivity.kt | 53 ++-- .../droidninja/filepicker/PickerManager.kt | 9 +- .../filepicker/adapters/FileListAdapter.kt | 35 ++- .../filepicker/adapters/FolderGridAdapter.kt | 33 +- .../filepicker/adapters/PhotoGridAdapter.kt | 41 +-- .../adapters/SectionsPagerAdapter.kt | 3 +- .../filepicker/adapters/SelectableAdapter.kt | 10 +- .../filepicker/fragments/BaseFragment.kt | 3 - .../filepicker/fragments/DocFragment.kt | 33 +- .../filepicker/fragments/DocPickerFragment.kt | 16 +- .../fragments/MediaDetailPickerFragment.kt | 59 +++- .../fragments/MediaFolderPickerFragment.kt | 66 +++- .../fragments/MediaPickerFragment.kt | 42 ++- .../droidninja/filepicker/models/BaseFile.kt | 9 +- .../droidninja/filepicker/models/Document.kt | 13 +- .../droidninja/filepicker/models/FileType.kt | 10 +- .../droidninja/filepicker/models/Media.kt | 12 +- .../filepicker/models/PhotoDirectory.kt | 14 +- .../filepicker/models/sort/NameComparator.kt | 3 +- .../filepicker/utils/AndroidLifecycleUtils.kt | 4 +- .../filepicker/utils/ContentUriUtils.kt | 16 +- .../filepicker/utils/FilePickerUtils.kt | 9 +- .../droidninja/filepicker/utils/FileUtils.kt | 5 +- .../filepicker/utils/FragmentUtil.kt | 24 +- .../utils/GridSpacingItemDecoration.kt | 24 +- .../filepicker/utils/ImageCaptureManager.kt | 21 +- .../filepicker/utils/TabLayoutHelper.java | 30 +- .../filepicker/viewmodels/BaseViewModel.kt | 1 - .../filepicker/viewmodels/VMDocPicker.kt | 63 ++-- .../filepicker/viewmodels/VMMediaPicker.kt | 67 ++-- .../filepicker/views/SmoothCheckBox.kt | 70 +++-- .../filepicker/views/SquareRelativeLayout.kt | 18 +- gradle.properties | 2 + gradle/wrapper/gradle-wrapper.properties | 4 +- 45 files changed, 752 insertions(+), 688 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fff3161..1b863b4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,19 @@ apply plugin: 'com.android.application' + apply plugin: 'kotlin-android' -//apply plugin: 'kotlin-parcelize' -apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-parcelize' android { - compileSdkVersion 30 + compileSdk 35 + namespace 'vi.filepicker' defaultConfig { applicationId "vi.filepicker" minSdkVersion 23 - targetSdkVersion 30 - versionCode 13 - versionName "1.3.0" + targetSdkVersion 35 + + versionCode 15 + versionName "1.5.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -21,23 +23,20 @@ android { } } - /*buildFeatures { + buildFeatures { buildConfig = true - viewBinding = true - } - kotlin { - jvmToolchain { - JavaVersion.VERSION_1_8 - } - }*/ - /*compileOptions { - targetCompatibility JavaVersion.VERSION_1_8 - sourceCompatibility JavaVersion.VERSION_1_8 } - lintOptions { + kotlinOptions { + jvmTarget = "17" + } + compileOptions { + targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_17 + } + lint { checkReleaseBuilds false - }*/ + } } dependencies { @@ -47,19 +46,18 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.3.2' - implementation "com.github.xinyuez:easypermissions:2.0.1" implementation 'com.google.android.material:material:1.12.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + // Required for instrumented tests - androidTestImplementation 'androidx.annotation:annotation:1.1.0' - androidTestImplementation 'androidx.test:runner:1.5.2' - androidTestImplementation 'androidx.test:rules:1.5.0' + androidTestImplementation 'androidx.annotation:annotation:1.9.0' + androidTestImplementation 'androidx.test:runner:1.6.2' + androidTestImplementation 'androidx.test:rules:1.6.1' // Optional -- UI testing with Espresso - androidTestImplementation('androidx.test.espresso:espresso-core:3.5.1', { + androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1', { exclude group: 'com.android.support', module: 'support-annotations' }) - androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1' - androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1' - -// compile 'com.squareup.leakcanary:leakcanary-android:1.5.1' + androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1' + androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8291d85..b41c5b5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + @@ -12,14 +11,16 @@ android:supportsRtl="true" android:requestLegacyExternalStorage="true" android:theme="@style/AppTheme"> - + - + + android:resource="@xml/file_paths" /> - \ No newline at end of file diff --git a/app/src/main/java/vi/filepicker/CallerFragment.java b/app/src/main/java/vi/filepicker/CallerFragment.java index ec8098a..1930453 100644 --- a/app/src/main/java/vi/filepicker/CallerFragment.java +++ b/app/src/main/java/vi/filepicker/CallerFragment.java @@ -4,201 +4,158 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.DefaultItemAnimator; -import androidx.recyclerview.widget.OrientationHelper; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.StaggeredGridLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; -import droidninja.filepicker.FilePickerBuilder; -import droidninja.filepicker.FilePickerConst; -import droidninja.filepicker.fragments.BaseFragment; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DefaultItemAnimator; +import androidx.recyclerview.widget.OrientationHelper; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.List; +import droidninja.filepicker.FilePickerBuilder; +import droidninja.filepicker.FilePickerConst; +import droidninja.filepicker.fragments.BaseFragment; import droidninja.filepicker.utils.ContentUriUtils; -import pub.devrel.easypermissions.AfterPermissionGranted; -import pub.devrel.easypermissions.AppSettingsDialog; -import pub.devrel.easypermissions.EasyPermissions; - -import static vi.filepicker.MainActivity.RC_FILE_PICKER_PERM; -import static vi.filepicker.MainActivity.RC_PHOTO_PICKER_PERM; /** * A simple {@link Fragment} subclass. */ -public class CallerFragment extends BaseFragment implements EasyPermissions.PermissionCallbacks { - private int MAX_ATTACHMENT_COUNT = 10; - private ArrayList photoPaths = new ArrayList<>(); - private ArrayList docPaths = new ArrayList<>(); - - public CallerFragment() { - // Required empty public constructor - } - - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.activity_main, container, false); - Button openFragmentBtn = view.findViewById(R.id.open_fragment); - openFragmentBtn.setVisibility(View.GONE); - view.findViewById(R.id.pick_photo).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - pickPhoto(); - } - }); - view.findViewById(R.id.pick_doc).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - pickDoc(); - } - }); - return view; - } - - @AfterPermissionGranted(RC_PHOTO_PICKER_PERM) - public void pickPhoto() { - if (EasyPermissions.hasPermissions(getContext(), FilePickerConst.PERMISSIONS_FILE_PICKER)) { - onPickPhoto(); - } else { - // Ask for one permission - EasyPermissions.requestPermissions( - this, - getString(R.string.rationale_photo_picker), - RC_PHOTO_PICKER_PERM, - FilePickerConst.PERMISSIONS_FILE_PICKER); - } - } - - @AfterPermissionGranted(RC_FILE_PICKER_PERM) - public void pickDoc() { - if (EasyPermissions.hasPermissions(getContext(), FilePickerConst.PERMISSIONS_FILE_PICKER)) { - onPickDoc(); - } else { - // Ask for one permission - EasyPermissions.requestPermissions( - this, - getString(R.string.rationale_doc_picker), - RC_FILE_PICKER_PERM, - FilePickerConst.PERMISSIONS_FILE_PICKER); - } - } - - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case FilePickerConst.REQUEST_CODE_PHOTO: - if (resultCode == Activity.RESULT_OK && data != null) { - ArrayList dataList = data.getParcelableArrayListExtra(FilePickerConst.KEY_SELECTED_MEDIA); - if(dataList != null) { - photoPaths = new ArrayList(); - photoPaths.addAll(dataList); - } - } - break; - - case FilePickerConst.REQUEST_CODE_DOC: - if (resultCode == Activity.RESULT_OK && data != null) { - ArrayList dataList = data.getParcelableArrayListExtra(FilePickerConst.KEY_SELECTED_MEDIA); - if(dataList != null) { - docPaths = new ArrayList<>(); - docPaths.addAll(dataList); - } - } - break; +public class CallerFragment extends BaseFragment { + private final int MAX_ATTACHMENT_COUNT = 10; + private ArrayList photoPaths = new ArrayList<>(); + private ArrayList docPaths = new ArrayList<>(); + + public CallerFragment() { + // Required empty public constructor } - addThemToView(photoPaths, docPaths); - } - - private void addThemToView(ArrayList imagePaths, ArrayList docPaths) { - ArrayList filePaths = new ArrayList<>(); - if (imagePaths != null) filePaths.addAll(imagePaths); - - if (docPaths != null) filePaths.addAll(docPaths); - - final RecyclerView recyclerView = (RecyclerView) getView().findViewById(R.id.recyclerview); - if (recyclerView != null) { - StaggeredGridLayoutManager layoutManager = - new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL); - layoutManager.setGapStrategy( - StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS); - recyclerView.setLayoutManager(layoutManager); - - ImageAdapter imageAdapter = new ImageAdapter(getActivity(), filePaths, new ImageAdapter.ImageAdapterListener() { - @Override - public void onItemClick(Uri uri) { - try { - //make sure to use this getFilePath method from worker thread - String path = ContentUriUtils.INSTANCE.getFilePath(recyclerView.getContext(), uri); - if (path != null) { - Toast.makeText(recyclerView.getContext(), path, Toast.LENGTH_SHORT).show(); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.activity_main, container, false); + Button openFragmentBtn = view.findViewById(R.id.open_fragment); + openFragmentBtn.setVisibility(View.GONE); + view.findViewById(R.id.pick_photo).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + pickPhoto(); } - } catch (URISyntaxException e) { - e.printStackTrace(); - } - } - }); - - recyclerView.setAdapter(imageAdapter); - recyclerView.setItemAnimator(new DefaultItemAnimator()); + }); + view.findViewById(R.id.pick_doc).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + pickDoc(); + } + }); + return view; } - Toast.makeText(getActivity(), "Num of files selected: " + filePaths.size(), Toast.LENGTH_SHORT) - .show(); - } - - public void onPickPhoto() { - int maxCount = MAX_ATTACHMENT_COUNT - docPaths.size(); - if ((docPaths.size() + photoPaths.size()) == MAX_ATTACHMENT_COUNT) { - Toast.makeText(getActivity(), "Cannot select more than " + MAX_ATTACHMENT_COUNT + " items", - Toast.LENGTH_SHORT).show(); - } else { - FilePickerBuilder.Companion.getInstance() - .setMaxCount(maxCount) - .setSelectedFiles(photoPaths) - .setActivityTheme(R.style.FilePickerTheme) - .pickPhoto(this); + public void pickPhoto() { + onPickPhoto(); } - } - - public void onPickDoc() { - int maxCount = MAX_ATTACHMENT_COUNT - photoPaths.size(); - if ((docPaths.size() + photoPaths.size()) == MAX_ATTACHMENT_COUNT) { - Toast.makeText(getActivity(), "Cannot select more than " + MAX_ATTACHMENT_COUNT + " items", - Toast.LENGTH_SHORT).show(); - } else { - FilePickerBuilder.Companion.getInstance() - .setMaxCount(maxCount) - .setSelectedFiles(docPaths) - .enableDocSupport(true) - .setActivityTheme(R.style.FilePickerTheme) - .pickFile(this); + + public void pickDoc() { + onPickDoc(); } - } - @Override public void onPermissionsGranted(int requestCode, @NonNull List perms) { - } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case FilePickerConst.REQUEST_CODE_PHOTO: + if (resultCode == Activity.RESULT_OK && data != null) { + ArrayList dataList = data.getParcelableArrayListExtra(FilePickerConst.KEY_SELECTED_MEDIA); + if (dataList != null) { + photoPaths = new ArrayList(); + photoPaths.addAll(dataList); + } + } + break; + + case FilePickerConst.REQUEST_CODE_DOC: + if (resultCode == Activity.RESULT_OK && data != null) { + ArrayList dataList = data.getParcelableArrayListExtra(FilePickerConst.KEY_SELECTED_MEDIA); + if (dataList != null) { + docPaths = new ArrayList<>(); + docPaths.addAll(dataList); + } + } + break; + } + + addThemToView(photoPaths, docPaths); + } - @Override public void onPermissionsDenied(int requestCode, @NonNull List perms) { + private void addThemToView(ArrayList imagePaths, ArrayList docPaths) { + ArrayList filePaths = new ArrayList<>(); + if (imagePaths != null) filePaths.addAll(imagePaths); + + if (docPaths != null) filePaths.addAll(docPaths); + + final RecyclerView recyclerView = getView().findViewById(R.id.recyclerview); + if (recyclerView != null) { + StaggeredGridLayoutManager layoutManager = + new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL); + layoutManager.setGapStrategy( + StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS); + recyclerView.setLayoutManager(layoutManager); + + ImageAdapter imageAdapter = new ImageAdapter(getActivity(), filePaths, new ImageAdapter.ImageAdapterListener() { + @Override + public void onItemClick(Uri uri) { + try { + //make sure to use this getFilePath method from worker thread + String path = ContentUriUtils.INSTANCE.getFilePath(recyclerView.getContext(), uri); + if (path != null) { + Toast.makeText(recyclerView.getContext(), path, Toast.LENGTH_SHORT).show(); + } + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + }); + + recyclerView.setAdapter(imageAdapter); + recyclerView.setItemAnimator(new DefaultItemAnimator()); + } - if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { - new AppSettingsDialog.Builder(this).build().show(); + Toast.makeText(getActivity(), "Num of files selected: " + filePaths.size(), Toast.LENGTH_SHORT) + .show(); } - } - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); + public void onPickPhoto() { + int maxCount = MAX_ATTACHMENT_COUNT - docPaths.size(); + if ((docPaths.size() + photoPaths.size()) == MAX_ATTACHMENT_COUNT) { + Toast.makeText(getActivity(), "Cannot select more than " + MAX_ATTACHMENT_COUNT + " items", + Toast.LENGTH_SHORT).show(); + } else { + FilePickerBuilder.Companion.getInstance() + .setMaxCount(maxCount) + .setSelectedFiles(photoPaths) + .setActivityTheme(R.style.FilePickerTheme) + .pickPhoto(this); + } + } - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); - } + public void onPickDoc() { + int maxCount = MAX_ATTACHMENT_COUNT - photoPaths.size(); + if ((docPaths.size() + photoPaths.size()) == MAX_ATTACHMENT_COUNT) { + Toast.makeText(getActivity(), "Cannot select more than " + MAX_ATTACHMENT_COUNT + " items", + Toast.LENGTH_SHORT).show(); + } else { + FilePickerBuilder.Companion.getInstance() + .setMaxCount(maxCount) + .setSelectedFiles(docPaths) + .enableDocSupport(true) + .setActivityTheme(R.style.FilePickerTheme) + .pickFile(this); + } + } } diff --git a/app/src/main/java/vi/filepicker/FragmentActivity.java b/app/src/main/java/vi/filepicker/FragmentActivity.java index 6650c5f..d9a9a02 100644 --- a/app/src/main/java/vi/filepicker/FragmentActivity.java +++ b/app/src/main/java/vi/filepicker/FragmentActivity.java @@ -1,7 +1,9 @@ package vi.filepicker; import android.os.Bundle; + import androidx.appcompat.app.AppCompatActivity; + import droidninja.filepicker.utils.FragmentUtil; public class FragmentActivity extends AppCompatActivity { @@ -16,6 +18,6 @@ protected void onCreate(Bundle savedInstanceState) { private void initView() { CallerFragment callerFragment = new CallerFragment(); - FragmentUtil.INSTANCE.addFragment(this, R.id.container,callerFragment); + FragmentUtil.INSTANCE.addFragment(this, R.id.container, callerFragment); } } diff --git a/app/src/main/java/vi/filepicker/ImageAdapter.java b/app/src/main/java/vi/filepicker/ImageAdapter.java index 4d42901..e7a6223 100644 --- a/app/src/main/java/vi/filepicker/ImageAdapter.java +++ b/app/src/main/java/vi/filepicker/ImageAdapter.java @@ -1,10 +1,6 @@ package vi.filepicker; import android.content.Context; - -import androidx.appcompat.widget.AppCompatImageView; -import androidx.recyclerview.widget.RecyclerView; - import android.net.Uri; import android.util.DisplayMetrics; import android.view.LayoutInflater; @@ -12,10 +8,12 @@ import android.view.ViewGroup; import android.view.WindowManager; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.recyclerview.widget.RecyclerView; + import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; -import java.io.File; import java.util.ArrayList; /** @@ -24,15 +22,9 @@ public class ImageAdapter extends RecyclerView.Adapter { private final ImageAdapterListener imageAdapterListener; - - public interface ImageAdapterListener { - void onItemClick(Uri uri); - } - private final ArrayList paths; private final Context context; private int imageSize; - public ImageAdapter(Context context, ArrayList paths, ImageAdapterListener imageAdapterListener) { this.context = context; this.paths = paths; @@ -81,6 +73,10 @@ public int getItemCount() { return paths.size(); } + public interface ImageAdapterListener { + void onItemClick(Uri uri); + } + public static class FileViewHolder extends RecyclerView.ViewHolder { AppCompatImageView imageView; diff --git a/app/src/main/java/vi/filepicker/MainActivity.java b/app/src/main/java/vi/filepicker/MainActivity.java index 2f0bd51..0daec32 100644 --- a/app/src/main/java/vi/filepicker/MainActivity.java +++ b/app/src/main/java/vi/filepicker/MainActivity.java @@ -8,7 +8,6 @@ import android.view.View; import android.widget.Toast; -import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.OrientationHelper; @@ -17,22 +16,18 @@ import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.List; import droidninja.filepicker.FilePickerBuilder; import droidninja.filepicker.FilePickerConst; import droidninja.filepicker.models.sort.SortingTypes; import droidninja.filepicker.utils.ContentUriUtils; -import pub.devrel.easypermissions.AfterPermissionGranted; -import pub.devrel.easypermissions.AppSettingsDialog; -import pub.devrel.easypermissions.EasyPermissions; -public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { +public class MainActivity extends AppCompatActivity { public static final int RC_PHOTO_PICKER_PERM = 123; public static final int RC_FILE_PICKER_PERM = 321; private static final int CUSTOM_REQUEST_CODE = 532; - private int MAX_ATTACHMENT_COUNT = 10; + private final int MAX_ATTACHMENT_COUNT = 10; private ArrayList photoPaths = new ArrayList<>(); private ArrayList docPaths = new ArrayList<>(); @@ -54,26 +49,12 @@ public void onClick(View view) { }); } - @AfterPermissionGranted(RC_PHOTO_PICKER_PERM) public void pickPhotoClicked() { - if (EasyPermissions.hasPermissions(this, FilePickerConst.PERMISSIONS_FILE_PICKER)) { - onPickPhoto(); - } else { - // Ask for one permission - EasyPermissions.requestPermissions(this, getString(R.string.rationale_photo_picker), - RC_PHOTO_PICKER_PERM, FilePickerConst.PERMISSIONS_FILE_PICKER); - } + onPickPhoto(); } - @AfterPermissionGranted(RC_FILE_PICKER_PERM) public void pickDocClicked() { - if (EasyPermissions.hasPermissions(this, FilePickerConst.PERMISSIONS_FILE_PICKER)) { - onPickDoc(); - } else { - // Ask for one permission - EasyPermissions.requestPermissions(this, getString(R.string.rationale_doc_picker), - RC_FILE_PICKER_PERM, FilePickerConst.PERMISSIONS_FILE_PICKER); - } + onPickDoc(); } @Override @@ -192,28 +173,8 @@ public void onPickDoc() { } } - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, - @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); - } - public void onOpenFragmentClicked(View view) { Intent intent = new Intent(this, FragmentActivity.class); startActivity(intent); } - - @Override - public void onPermissionsGranted(int requestCode, @NonNull List perms) { - } - - @Override - public void onPermissionsDenied(int requestCode, @NonNull List perms) { - - if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { - new AppSettingsDialog.Builder(this).build().show(); - } - } } diff --git a/build.gradle b/build.gradle index 4debfb3..4fbd278 100644 --- a/build.gradle +++ b/build.gradle @@ -1,20 +1,22 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { - agp_version = '4.1.1' - kotlin_version = '1.4.10' + agp_version = '8.7.1' + kotlin_version = '2.0.21' } repositories { google() + + mavenCentral() + //noinspection JcenterRepositoryObsolete jcenter() + maven { url "https://jitpack.io" } } dependencies { classpath "com.android.tools.build:gradle:$agp_version" - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -22,16 +24,18 @@ buildscript { allprojects { repositories { google() + + mavenCentral() + //noinspection JcenterRepositoryObsolete jcenter() - maven { url 'https://maven.google.com' } + maven { url "https://jitpack.io" } } } tasks.register('clean', Delete) { - delete rootProject.buildDir + delete rootProject.layout.buildDirectory } - subprojects { tasks.withType(Javadoc).configureEach { enabled = false } -} +} \ No newline at end of file diff --git a/filepicker/build.gradle b/filepicker/build.gradle index e748714..d6aef0e 100644 --- a/filepicker/build.gradle +++ b/filepicker/build.gradle @@ -1,20 +1,15 @@ apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' -//apply plugin: 'kotlin-parcelize' -apply plugin: 'kotlin-android-extensions' -apply plugin: 'com.github.dcendents.android-maven' -apply plugin: "com.jfrog.bintray" -version = "1.3.0" +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-parcelize' android { - compileSdkVersion 30 + compileSdk 35 + namespace 'droidninja.filepicker' defaultConfig { minSdkVersion 23 - targetSdkVersion 30 - versionCode 13 - versionName version + targetSdkVersion 35 } buildTypes { release { @@ -23,78 +18,38 @@ android { } } - /*buildFeatures { + buildFeatures { buildConfig = true - viewBinding = true } - kotlin { - jvmToolchain { - JavaVersion.VERSION_1_8 - } - }*/ - /*compileOptions { - targetCompatibility JavaVersion.VERSION_1_8 - sourceCompatibility JavaVersion.VERSION_1_8 + + kotlinOptions { + jvmTarget = "17" + } + compileOptions { + targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_17 } - lintOptions { + lint { checkReleaseBuilds false - }*/ + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.2.1' - implementation 'androidx.recyclerview:recyclerview:1.1.0' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' - api 'com.github.bumptech.glide:glide:4.11.0' - annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' - testImplementation 'junit:junit:4.12' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' + implementation 'androidx.recyclerview:recyclerview:1.3.2' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} - -def siteUrl = 'https://github.com/DroidNinja/Android-FilePicker' // Homepage URL of the library -def gitUrl = 'https://github.com/DroidNinja/Android-FilePicker.git' // Git repository URL -group = "com.droidninja" // Maven Group ID for the artifact + api 'com.github.bumptech.glide:glide:4.16.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0' -install { - repositories.mavenInstaller { - // This generates POM.xml with proper parameters - pom { - project { - packaging 'aar' + testImplementation 'junit:junit:4.13.2' - // Add your description here - name 'com.droidninja.filepicker' - description = 'Media and document picker' - url siteUrl - - // Set your license - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - developers { - developer { - id 'droidninja' - name 'Arun Sharma' - email 'arun2007ind@gmail.com' - } - } - scm { - connection gitUrl - developerConnection gitUrl - url siteUrl - } - } - } - } + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } tasks.register('sourcesJar', Jar) { @@ -111,44 +66,5 @@ tasks.register('javadoc', Javadoc) { classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } -tasks.register('javadocJar', Jar) { - dependsOn javadoc - classifier = 'javadoc' - from javadoc.destinationDir -} - -artifacts { - archives javadocJar - archives sourcesJar -} - Properties properties = new Properties() -properties.load(project.rootProject.file('local.properties').newDataInputStream()) - -// https://github.com/bintray/gradle-bintray-plugin -bintray { - user = properties.getProperty("bintray.user") - key = properties.getProperty("bintray.apikey") - - configurations = ['archives'] - pkg { - repo = "maven" - // it is the name that appears in bintray when logged - name = "com.droidninja.filepicker" // TODO - websiteUrl = siteUrl - vcsUrl = gitUrl - licenses = ["Apache-2.0"] - publish = true - version { - gpg { - sign = true //Determines whether to GPG sign the files. The default is false - passphrase = properties.getProperty("bintray.gpg.password") - //Optional. The passphrase for GPG signing' - } - } - } -} -repositories { - mavenCentral() - maven { url "https://jitpack.io" } -} \ No newline at end of file +properties.load(project.rootProject.file('local.properties').newDataInputStream()) \ No newline at end of file diff --git a/filepicker/src/main/AndroidManifest.xml b/filepicker/src/main/AndroidManifest.xml index 77736c4..b76b60c 100644 --- a/filepicker/src/main/AndroidManifest.xml +++ b/filepicker/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> diff --git a/filepicker/src/main/java/droidninja/filepicker/FilePickerActivity.kt b/filepicker/src/main/java/droidninja/filepicker/FilePickerActivity.kt index 3ec38f0..61e4560 100644 --- a/filepicker/src/main/java/droidninja/filepicker/FilePickerActivity.kt +++ b/filepicker/src/main/java/droidninja/filepicker/FilePickerActivity.kt @@ -1,7 +1,6 @@ package droidninja.filepicker import android.annotation.SuppressLint -import android.app.Activity import android.content.Intent import android.net.Uri import android.os.Bundle @@ -15,7 +14,9 @@ import droidninja.filepicker.fragments.PhotoPickerFragmentListener import droidninja.filepicker.utils.FragmentUtil import java.util.* -class FilePickerActivity : BaseFilePickerActivity(), PhotoPickerFragmentListener, DocFragment.DocFragmentListener, DocPickerFragment.DocPickerFragmentListener, MediaPickerFragment.MediaPickerFragmentListener { +class FilePickerActivity : BaseFilePickerActivity(), PhotoPickerFragmentListener, + DocFragment.DocFragmentListener, DocPickerFragment.DocPickerFragmentListener, + MediaPickerFragment.MediaPickerFragmentListener { private var type: Int = 0 @SuppressLint("MissingSuperCall") @@ -26,8 +27,10 @@ class FilePickerActivity : BaseFilePickerActivity(), PhotoPickerFragmentListener override fun initView() { val intent = intent if (intent != null) { - val selectedPaths: ArrayList? = intent.getParcelableArrayListExtra(FilePickerConst.KEY_SELECTED_MEDIA) - type = intent.getIntExtra(FilePickerConst.EXTRA_PICKER_TYPE, FilePickerConst.MEDIA_PICKER) + val selectedPaths: ArrayList? = + intent.getParcelableArrayListExtra(FilePickerConst.KEY_SELECTED_MEDIA) + type = + intent.getIntExtra(FilePickerConst.EXTRA_PICKER_TYPE, FilePickerConst.MEDIA_PICKER) if (selectedPaths != null) { @@ -55,7 +58,8 @@ class FilePickerActivity : BaseFilePickerActivity(), PhotoPickerFragmentListener if (maxCount == -1 && count > 0) { actionBar.title = String.format(getString(R.string.attachments_num), count) } else if (maxCount > 0 && count > 0) { - actionBar.title = String.format(getString(R.string.attachments_title_text), count, maxCount) + actionBar.title = + String.format(getString(R.string.attachments_title_text), count, maxCount) } else if (!TextUtils.isEmpty(PickerManager.title)) { actionBar.title = PickerManager.title } else { @@ -108,14 +112,14 @@ class FilePickerActivity : BaseFilePickerActivity(), PhotoPickerFragmentListener override fun onBackPressed() { super.onBackPressed() - setResult(Activity.RESULT_CANCELED) + setResult(RESULT_CANCELED) finish() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { - FilePickerConst.REQUEST_CODE_MEDIA_DETAIL -> if (resultCode == Activity.RESULT_OK) { + FilePickerConst.REQUEST_CODE_MEDIA_DETAIL -> if (resultCode == RESULT_OK) { if (type == FilePickerConst.MEDIA_PICKER) { returnData(PickerManager.selectedPhotos) } else { @@ -135,7 +139,7 @@ class FilePickerActivity : BaseFilePickerActivity(), PhotoPickerFragmentListener intent.putParcelableArrayListExtra(FilePickerConst.KEY_SELECTED_DOCS, paths) } - setResult(Activity.RESULT_OK, intent) + setResult(RESULT_OK, intent) finish() } @@ -150,10 +154,11 @@ class FilePickerActivity : BaseFilePickerActivity(), PhotoPickerFragmentListener if (PickerManager.getMaxCount() == 1 && currentCount == 1) { returnData( - if (type == FilePickerConst.MEDIA_PICKER) - PickerManager.selectedPhotos - else - PickerManager.selectedFiles) + if (type == FilePickerConst.MEDIA_PICKER) + PickerManager.selectedPhotos + else + PickerManager.selectedFiles + ) } } diff --git a/filepicker/src/main/java/droidninja/filepicker/FilePickerConst.kt b/filepicker/src/main/java/droidninja/filepicker/FilePickerConst.kt index e5c816f..e55689f 100644 --- a/filepicker/src/main/java/droidninja/filepicker/FilePickerConst.kt +++ b/filepicker/src/main/java/droidninja/filepicker/FilePickerConst.kt @@ -52,7 +52,7 @@ object FilePickerConst { PDF, WORD, EXCEL, PPT, TXT, UNKNOWN } - enum class SPAN_TYPE{ + enum class SPAN_TYPE { FOLDER_SPAN, DETAIL_SPAN } } diff --git a/filepicker/src/main/java/droidninja/filepicker/MediaDetailsActivity.kt b/filepicker/src/main/java/droidninja/filepicker/MediaDetailsActivity.kt index 3ae9b85..cabd600 100644 --- a/filepicker/src/main/java/droidninja/filepicker/MediaDetailsActivity.kt +++ b/filepicker/src/main/java/droidninja/filepicker/MediaDetailsActivity.kt @@ -1,18 +1,17 @@ package droidninja.filepicker import android.annotation.SuppressLint -import android.app.Activity import android.os.Bundle -import androidx.recyclerview.widget.DefaultItemAnimator -import androidx.recyclerview.widget.OrientationHelper -import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.StaggeredGridLayoutManager import android.view.Menu import android.view.MenuItem import android.view.View import android.widget.TextView import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.OrientationHelper +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.bumptech.glide.Glide import com.bumptech.glide.RequestManager import droidninja.filepicker.adapters.FileAdapterListener @@ -21,8 +20,6 @@ import droidninja.filepicker.models.Media import droidninja.filepicker.models.PhotoDirectory import droidninja.filepicker.utils.AndroidLifecycleUtils import droidninja.filepicker.viewmodels.VMMediaPicker -import java.util.ArrayList -import java.util.Comparator class MediaDetailsActivity : BaseFilePickerActivity(), FileAdapterListener { private var recyclerView: RecyclerView? = null @@ -42,14 +39,26 @@ class MediaDetailsActivity : BaseFilePickerActivity(), FileAdapterListener { } override fun initView() { - viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application)).get(VMMediaPicker::class.java) + viewModel = + ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application)).get( + VMMediaPicker::class.java + ) mGlideRequestManager = Glide.with(this) val intent = intent if (intent != null) { - fileType = intent.getIntExtra(FilePickerConst.EXTRA_FILE_TYPE, FilePickerConst.MEDIA_TYPE_IMAGE) - imageFileSize = intent.getIntExtra(FilePickerConst.EXTRA_IMAGE_FILE_SIZE, FilePickerConst.DEFAULT_FILE_SIZE) - videoFileSize = intent.getIntExtra(FilePickerConst.EXTRA_VIDEO_FILE_SIZE, FilePickerConst.DEFAULT_FILE_SIZE) + fileType = intent.getIntExtra( + FilePickerConst.EXTRA_FILE_TYPE, + FilePickerConst.MEDIA_TYPE_IMAGE + ) + imageFileSize = intent.getIntExtra( + FilePickerConst.EXTRA_IMAGE_FILE_SIZE, + FilePickerConst.DEFAULT_FILE_SIZE + ) + videoFileSize = intent.getIntExtra( + FilePickerConst.EXTRA_VIDEO_FILE_SIZE, + FilePickerConst.DEFAULT_FILE_SIZE + ) photoDirectory = intent.getParcelableExtra(PhotoDirectory::class.java.simpleName) if (photoDirectory != null) { setUpView() @@ -66,7 +75,8 @@ class MediaDetailsActivity : BaseFilePickerActivity(), FileAdapterListener { if (maxCount == -1 && count > 0) { actionBar.title = String.format(getString(R.string.attachments_num), count) } else if (maxCount > 0 && count > 0) { - actionBar.title = String.format(getString(R.string.attachments_title_text), count, maxCount) + actionBar.title = + String.format(getString(R.string.attachments_title_text), count, maxCount) } else { actionBar.title = photoDirectory?.name } @@ -104,7 +114,12 @@ class MediaDetailsActivity : BaseFilePickerActivity(), FileAdapterListener { viewModel.lvMediaData.observe(this, Observer { data -> updateList(data) }) - viewModel.getMedia(bucketId = photoDirectory?.bucketId, mediaType = fileType, imageFileSize = imageFileSize, videoFileSize = videoFileSize) + viewModel.getMedia( + bucketId = photoDirectory?.bucketId, + mediaType = fileType, + imageFileSize = imageFileSize, + videoFileSize = videoFileSize + ) } private fun updateList(medias: List) { @@ -120,8 +135,10 @@ class MediaDetailsActivity : BaseFilePickerActivity(), FileAdapterListener { if (photoGridAdapter != null) { photoGridAdapter?.setData(medias, PickerManager.selectedPhotos) } else { - photoGridAdapter = PhotoGridAdapter(this, mGlideRequestManager, medias, - PickerManager.selectedPhotos, false, this) + photoGridAdapter = PhotoGridAdapter( + this, mGlideRequestManager, medias, + PickerManager.selectedPhotos, false, this + ) recyclerView?.adapter = photoGridAdapter } @@ -156,7 +173,7 @@ class MediaDetailsActivity : BaseFilePickerActivity(), FileAdapterListener { override fun onOptionsItemSelected(item: MenuItem): Boolean { val itemId = item.itemId if (itemId == R.id.action_done) { - setResult(Activity.RESULT_OK, null) + setResult(RESULT_OK, null) finish() return true @@ -188,14 +205,14 @@ class MediaDetailsActivity : BaseFilePickerActivity(), FileAdapterListener { override fun onItemSelected() { val maxCount = PickerManager.getMaxCount() if (maxCount == 1) { - setResult(Activity.RESULT_OK, null) + setResult(RESULT_OK, null) finish() } setTitle(PickerManager.currentCount) } override fun onBackPressed() { - setResult(Activity.RESULT_CANCELED, null) + setResult(RESULT_CANCELED, null) finish() } diff --git a/filepicker/src/main/java/droidninja/filepicker/PickerManager.kt b/filepicker/src/main/java/droidninja/filepicker/PickerManager.kt index 0249493..b7d5370 100644 --- a/filepicker/src/main/java/droidninja/filepicker/PickerManager.kt +++ b/filepicker/src/main/java/droidninja/filepicker/PickerManager.kt @@ -2,11 +2,10 @@ package droidninja.filepicker import android.content.pm.ActivityInfo import android.net.Uri -import java.util.ArrayList - import droidninja.filepicker.models.BaseFile import droidninja.filepicker.models.FileType import droidninja.filepicker.models.sort.SortingTypes +import java.util.ArrayList import java.util.LinkedHashSet /** @@ -37,7 +36,6 @@ object PickerManager { var videoFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE var isDocSupport = true - get() = field var isEnableCamera = true @@ -47,8 +45,8 @@ object PickerManager { * Default Detail Span is 3 */ var spanTypes = mutableMapOf( - FilePickerConst.SPAN_TYPE.FOLDER_SPAN to 2, - FilePickerConst.SPAN_TYPE.DETAIL_SPAN to 3 + FilePickerConst.SPAN_TYPE.FOLDER_SPAN to 2, + FilePickerConst.SPAN_TYPE.DETAIL_SPAN to 3 ) /** @@ -72,7 +70,6 @@ object PickerManager { * {@link #SCREEN_ORIENTATION_LOCKED}, */ var orientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - get() = field var isShowFolderView = true diff --git a/filepicker/src/main/java/droidninja/filepicker/adapters/FileListAdapter.kt b/filepicker/src/main/java/droidninja/filepicker/adapters/FileListAdapter.kt index 7f085c1..310ccf8 100644 --- a/filepicker/src/main/java/droidninja/filepicker/adapters/FileListAdapter.kt +++ b/filepicker/src/main/java/droidninja/filepicker/adapters/FileListAdapter.kt @@ -2,7 +2,6 @@ package droidninja.filepicker.adapters import android.content.Context import android.net.Uri -import androidx.recyclerview.widget.RecyclerView import android.text.format.Formatter import android.view.LayoutInflater import android.view.View @@ -11,20 +10,24 @@ import android.widget.Filter import android.widget.Filterable import android.widget.ImageView import android.widget.TextView - -import java.util.ArrayList - +import androidx.recyclerview.widget.RecyclerView import droidninja.filepicker.FilePickerConst import droidninja.filepicker.PickerManager import droidninja.filepicker.R import droidninja.filepicker.models.Document import droidninja.filepicker.views.SmoothCheckBox +import java.util.ArrayList /** * Created by droidNinja on 29/07/16. */ -class FileListAdapter(private val context: Context, private var mFilteredList: List, selectedPaths: MutableList, - private val mListener: FileAdapterListener?) : SelectableAdapter(mFilteredList, selectedPaths), Filterable { +class FileListAdapter( + private val context: Context, + private var mFilteredList: List, + selectedPaths: MutableList, + private val mListener: FileAdapterListener? +) : SelectableAdapter(mFilteredList, selectedPaths), + Filterable { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileViewHolder { val itemView = LayoutInflater.from(context).inflate(R.layout.item_doc_layout, parent, false) @@ -45,8 +48,12 @@ class FileListAdapter(private val context: Context, private var mFilteredList: L } holder.fileNameTextView.text = document.name - holder.fileSizeTextView.text = Formatter.formatShortFileSize(context, java.lang.Long.parseLong(document.size - ?: "0")) + holder.fileSizeTextView.text = Formatter.formatShortFileSize( + context, java.lang.Long.parseLong( + document.size + ?: "0" + ) + ) holder.itemView.setOnClickListener { onItemClicked(document, holder) } @@ -58,7 +65,8 @@ class FileListAdapter(private val context: Context, private var mFilteredList: L holder.checkBox.isChecked = isSelected(document) holder.itemView.setBackgroundResource( - if (isSelected(document)) R.color.bg_gray else android.R.color.white) + if (isSelected(document)) R.color.bg_gray else android.R.color.white + ) holder.checkBox.visibility = if (isSelected(document)) View.VISIBLE else View.GONE holder.checkBox.setOnCheckedChangeListener(object : SmoothCheckBox.OnCheckedChangeListener { @@ -96,7 +104,7 @@ class FileListAdapter(private val context: Context, private var mFilteredList: L override fun getFilter(): Filter { return object : Filter() { - override fun performFiltering(charSequence: CharSequence): Filter.FilterResults { + override fun performFiltering(charSequence: CharSequence): FilterResults { val charString = charSequence.toString() @@ -118,13 +126,16 @@ class FileListAdapter(private val context: Context, private var mFilteredList: L mFilteredList = filteredList } - val filterResults = Filter.FilterResults() + val filterResults = FilterResults() filterResults.values = mFilteredList return filterResults } @Suppress("UNCHECKED_CAST") - override fun publishResults(charSequence: CharSequence, filterResults: Filter.FilterResults) { + override fun publishResults( + charSequence: CharSequence, + filterResults: FilterResults + ) { mFilteredList = filterResults.values as List notifyDataSetChanged() } diff --git a/filepicker/src/main/java/droidninja/filepicker/adapters/FolderGridAdapter.kt b/filepicker/src/main/java/droidninja/filepicker/adapters/FolderGridAdapter.kt index 12165c6..a74484b 100644 --- a/filepicker/src/main/java/droidninja/filepicker/adapters/FolderGridAdapter.kt +++ b/filepicker/src/main/java/droidninja/filepicker/adapters/FolderGridAdapter.kt @@ -1,7 +1,6 @@ package droidninja.filepicker.adapters import android.content.Context -import androidx.recyclerview.widget.RecyclerView import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.View @@ -9,19 +8,20 @@ import android.view.ViewGroup import android.view.WindowManager import android.widget.ImageView import android.widget.TextView - +import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.RequestManager import com.bumptech.glide.request.RequestOptions - -import java.io.File -import java.util.ArrayList - import droidninja.filepicker.PickerManager import droidninja.filepicker.R import droidninja.filepicker.models.PhotoDirectory import droidninja.filepicker.utils.AndroidLifecycleUtils -class FolderGridAdapter(private val context: Context, private val glide: RequestManager, var items: List, private val showCamera: Boolean) : RecyclerView.Adapter() { +class FolderGridAdapter( + private val context: Context, + private val glide: RequestManager, + var items: List, + private val showCamera: Boolean +) : RecyclerView.Adapter() { private var imageSize: Int = 0 private var folderGridAdapterListener: FolderGridAdapterListener? = null @@ -35,7 +35,8 @@ class FolderGridAdapter(private val context: Context, private val glide: Request } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PhotoViewHolder { - val itemView = LayoutInflater.from(context).inflate(R.layout.item_folder_layout, parent, false) + val itemView = + LayoutInflater.from(context).inflate(R.layout.item_folder_layout, parent, false) return PhotoViewHolder(itemView) } @@ -54,19 +55,21 @@ class FolderGridAdapter(private val context: Context, private val glide: Request if (AndroidLifecycleUtils.canLoadImage(holder.imageView.context)) { glide.load(photoDirectory.getCoverPath()) - .apply(RequestOptions - .centerCropTransform() - .override(imageSize, imageSize) - .placeholder(R.drawable.image_placeholder)) - .thumbnail(0.5f) - .into(holder.imageView) + .apply( + RequestOptions + .centerCropTransform() + .override(imageSize, imageSize) + .placeholder(R.drawable.image_placeholder) + ) + .thumbnail(0.5f) + .into(holder.imageView) } holder.folderTitle.text = photoDirectory.name holder.folderCount.text = photoDirectory.medias.size.toString() holder.itemView.setOnClickListener { - folderGridAdapterListener?.onFolderClicked(photoDirectory) + folderGridAdapterListener?.onFolderClicked(photoDirectory) } holder.bottomOverlay.visibility = View.VISIBLE } else { diff --git a/filepicker/src/main/java/droidninja/filepicker/adapters/PhotoGridAdapter.kt b/filepicker/src/main/java/droidninja/filepicker/adapters/PhotoGridAdapter.kt index 490f6c8..6471a51 100644 --- a/filepicker/src/main/java/droidninja/filepicker/adapters/PhotoGridAdapter.kt +++ b/filepicker/src/main/java/droidninja/filepicker/adapters/PhotoGridAdapter.kt @@ -2,20 +2,15 @@ package droidninja.filepicker.adapters import android.content.Context import android.net.Uri -import androidx.recyclerview.widget.RecyclerView import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.widget.ImageView - +import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.RequestManager import com.bumptech.glide.request.RequestOptions - -import java.io.File -import java.util.ArrayList - import droidninja.filepicker.FilePickerConst import droidninja.filepicker.PickerManager import droidninja.filepicker.R @@ -23,12 +18,14 @@ import droidninja.filepicker.models.Media import droidninja.filepicker.utils.AndroidLifecycleUtils import droidninja.filepicker.views.SmoothCheckBox -class PhotoGridAdapter(private val context: Context, - private val glide: RequestManager, - medias: List, - selectedPaths: MutableList, - private val showCamera: Boolean, - private val mListener: FileAdapterListener?) : SelectableAdapter(medias, selectedPaths) { +class PhotoGridAdapter( + private val context: Context, + private val glide: RequestManager, + medias: List, + selectedPaths: MutableList, + private val showCamera: Boolean, + private val mListener: FileAdapterListener? +) : SelectableAdapter(medias, selectedPaths) { private var imageSize: Int = 0 private var cameraOnClickListener: View.OnClickListener? = null @@ -37,7 +34,8 @@ class PhotoGridAdapter(private val context: Context, } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PhotoViewHolder { - val itemView = LayoutInflater.from(context).inflate(R.layout.item_photo_layout, parent, false) + val itemView = + LayoutInflater.from(context).inflate(R.layout.item_photo_layout, parent, false) return PhotoViewHolder(itemView) } @@ -56,12 +54,14 @@ class PhotoGridAdapter(private val context: Context, if (AndroidLifecycleUtils.canLoadImage(holder.imageView.context)) { glide.load(media.path) - .apply(RequestOptions - .centerCropTransform() - .override(imageSize, imageSize) - .placeholder(R.drawable.image_placeholder)) - .thumbnail(0.5f) - .into(holder.imageView) + .apply( + RequestOptions + .centerCropTransform() + .override(imageSize, imageSize) + .placeholder(R.drawable.image_placeholder) + ) + .thumbnail(0.5f) + .into(holder.imageView) } @@ -83,7 +83,8 @@ class PhotoGridAdapter(private val context: Context, holder.selectBg.visibility = if (isSelected(media)) View.VISIBLE else View.GONE holder.checkBox.visibility = if (isSelected(media)) View.VISIBLE else View.GONE - holder.checkBox.setOnCheckedChangeListener(object : SmoothCheckBox.OnCheckedChangeListener { + holder.checkBox.setOnCheckedChangeListener(object : + SmoothCheckBox.OnCheckedChangeListener { override fun onCheckedChanged(checkBox: SmoothCheckBox, isChecked: Boolean) { toggleSelection(media) holder.selectBg.visibility = if (isChecked) View.VISIBLE else View.GONE diff --git a/filepicker/src/main/java/droidninja/filepicker/adapters/SectionsPagerAdapter.kt b/filepicker/src/main/java/droidninja/filepicker/adapters/SectionsPagerAdapter.kt index 0f6b12a..b217938 100644 --- a/filepicker/src/main/java/droidninja/filepicker/adapters/SectionsPagerAdapter.kt +++ b/filepicker/src/main/java/droidninja/filepicker/adapters/SectionsPagerAdapter.kt @@ -5,7 +5,8 @@ import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentStatePagerAdapter import java.util.* -class SectionsPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { +class SectionsPagerAdapter(fm: FragmentManager) : + FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { private val mFragmentList = ArrayList() private val mFragmentTitles = ArrayList() diff --git a/filepicker/src/main/java/droidninja/filepicker/adapters/SelectableAdapter.kt b/filepicker/src/main/java/droidninja/filepicker/adapters/SelectableAdapter.kt index 6c9d3dc..2c177c6 100644 --- a/filepicker/src/main/java/droidninja/filepicker/adapters/SelectableAdapter.kt +++ b/filepicker/src/main/java/droidninja/filepicker/adapters/SelectableAdapter.kt @@ -2,16 +2,16 @@ package droidninja.filepicker.adapters import android.net.Uri import androidx.recyclerview.widget.RecyclerView - -import java.util.ArrayList - -import droidninja.filepicker.PickerManager import droidninja.filepicker.models.BaseFile -abstract class SelectableAdapter(var items: List, var selectedPaths: MutableList = mutableListOf()) : RecyclerView.Adapter(), Selectable { +abstract class SelectableAdapter( + var items: List, + var selectedPaths: MutableList = mutableListOf() +) : RecyclerView.Adapter(), Selectable { override val selectedItemCount: Int get() = selectedPaths.size + /** * Indicates if the item at position where is selected * diff --git a/filepicker/src/main/java/droidninja/filepicker/fragments/BaseFragment.kt b/filepicker/src/main/java/droidninja/filepicker/fragments/BaseFragment.kt index ece877c..2a13f60 100644 --- a/filepicker/src/main/java/droidninja/filepicker/fragments/BaseFragment.kt +++ b/filepicker/src/main/java/droidninja/filepicker/fragments/BaseFragment.kt @@ -1,9 +1,6 @@ package droidninja.filepicker.fragments import androidx.fragment.app.Fragment -import android.view.View -import android.view.animation.Animation -import android.view.animation.AnimationUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/filepicker/src/main/java/droidninja/filepicker/fragments/DocFragment.kt b/filepicker/src/main/java/droidninja/filepicker/fragments/DocFragment.kt index a96c1f6..dcc22a7 100644 --- a/filepicker/src/main/java/droidninja/filepicker/fragments/DocFragment.kt +++ b/filepicker/src/main/java/droidninja/filepicker/fragments/DocFragment.kt @@ -2,9 +2,6 @@ package droidninja.filepicker.fragments import android.content.Context import android.os.Bundle -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import androidx.appcompat.widget.SearchView import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater @@ -12,6 +9,9 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.TextView +import androidx.appcompat.widget.SearchView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import droidninja.filepicker.FilePickerConst import droidninja.filepicker.PickerManager import droidninja.filepicker.R @@ -30,10 +30,12 @@ class DocFragment : BaseFragment(), FileAdapterListener { private var fileListAdapter: FileListAdapter? = null val fileType: FileType? - get() = arguments?.getParcelable(BaseFragment.Companion.FILE_TYPE) + get() = arguments?.getParcelable(FILE_TYPE) - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_photo_picker, container, false) } @@ -44,7 +46,8 @@ class DocFragment : BaseFragment(), FileAdapterListener { mListener = context } else { throw RuntimeException( - "$context must implement PhotoPickerFragmentListener") + "$context must implement PhotoPickerFragmentListener" + ) } } @@ -60,7 +63,7 @@ class DocFragment : BaseFragment(), FileAdapterListener { override fun onItemSelected() { mListener?.onItemSelected() - fileListAdapter?.let { adapter-> + fileListAdapter?.let { adapter -> selectAllItem?.let { menuItem -> if (adapter.itemCount == adapter.selectedItemCount) { menuItem.setIcon(R.drawable.ic_select_all) @@ -95,8 +98,10 @@ class DocFragment : BaseFragment(), FileAdapterListener { context?.let { fileListAdapter = recyclerView.adapter as? FileListAdapter if (fileListAdapter == null) { - fileListAdapter = FileListAdapter(it, dirs, PickerManager.selectedFiles, - this) + fileListAdapter = FileListAdapter( + it, dirs, PickerManager.selectedFiles, + this + ) recyclerView.adapter = fileListAdapter } else { @@ -130,7 +135,7 @@ class DocFragment : BaseFragment(), FileAdapterListener { } override fun onQueryTextChange(newText: String): Boolean { - fileListAdapter?.filter?.filter(newText) + fileListAdapter?.filter?.filter(newText) return true } }) @@ -141,7 +146,7 @@ class DocFragment : BaseFragment(), FileAdapterListener { override fun onOptionsItemSelected(item: MenuItem): Boolean { val itemId = item.itemId if (itemId == R.id.action_select) { - fileListAdapter?.let { adapter-> + fileListAdapter?.let { adapter -> selectAllItem?.let { menuItem -> if (menuItem.isChecked) { adapter.clearSelection() @@ -151,7 +156,7 @@ class DocFragment : BaseFragment(), FileAdapterListener { } else { adapter.selectAll() PickerManager - .add(adapter.selectedPaths, FilePickerConst.FILE_TYPE_DOCUMENT) + .add(adapter.selectedPaths, FilePickerConst.FILE_TYPE_DOCUMENT) menuItem.setIcon(R.drawable.ic_select_all) } @@ -172,7 +177,7 @@ class DocFragment : BaseFragment(), FileAdapterListener { fun newInstance(fileType: FileType): DocFragment { val photoPickerFragment = DocFragment() val bun = Bundle() - bun.putParcelable(BaseFragment.Companion.FILE_TYPE, fileType) + bun.putParcelable(FILE_TYPE, fileType) photoPickerFragment.arguments = bun return photoPickerFragment } diff --git a/filepicker/src/main/java/droidninja/filepicker/fragments/DocPickerFragment.kt b/filepicker/src/main/java/droidninja/filepicker/fragments/DocPickerFragment.kt index 300eafc..2176e72 100644 --- a/filepicker/src/main/java/droidninja/filepicker/fragments/DocPickerFragment.kt +++ b/filepicker/src/main/java/droidninja/filepicker/fragments/DocPickerFragment.kt @@ -31,11 +31,16 @@ class DocPickerFragment : BaseFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) - viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(requireActivity().application)).get(VMDocPicker::class.java) + viewModel = ViewModelProvider( + this, + ViewModelProvider.AndroidViewModelFactory(requireActivity().application) + ).get(VMDocPicker::class.java) } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_doc_picker, container, false) } @@ -101,7 +106,10 @@ class DocPickerFragment : BaseFragment() { val adapter = SectionsPagerAdapter(childFragmentManager) val supportedTypes = PickerManager.getFileTypes() for (index in supportedTypes.indices) { - adapter.addFragment(DocFragment.newInstance(supportedTypes[index]), supportedTypes[index].title) + adapter.addFragment( + DocFragment.newInstance(supportedTypes[index]), + supportedTypes[index].title + ) } viewPager.offscreenPageLimit = supportedTypes.size diff --git a/filepicker/src/main/java/droidninja/filepicker/fragments/MediaDetailPickerFragment.kt b/filepicker/src/main/java/droidninja/filepicker/fragments/MediaDetailPickerFragment.kt index 9772586..f0b127e 100644 --- a/filepicker/src/main/java/droidninja/filepicker/fragments/MediaDetailPickerFragment.kt +++ b/filepicker/src/main/java/droidninja/filepicker/fragments/MediaDetailPickerFragment.kt @@ -46,8 +46,10 @@ class MediaDetailPickerFragment : BaseFragment(), FileAdapterListener { private var selectAllItem: MenuItem? = null - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_photo_picker, container, false) } @@ -82,7 +84,10 @@ class MediaDetailPickerFragment : BaseFragment(), FileAdapterListener { super.onCreate(savedInstanceState) setHasOptionsMenu(PickerManager.hasSelectAll()) mGlideRequestManager = Glide.with(this) - viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(requireActivity().application)).get(VMMediaPicker::class.java) + viewModel = ViewModelProvider( + this, + ViewModelProvider.AndroidViewModelFactory(requireActivity().application) + ).get(VMMediaPicker::class.java) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -94,7 +99,7 @@ class MediaDetailPickerFragment : BaseFragment(), FileAdapterListener { recyclerView = view.findViewById(R.id.recyclerview) emptyView = view.findViewById(R.id.empty_view) arguments?.let { - fileType = it.getInt(BaseFragment.FILE_TYPE) + fileType = it.getInt(FILE_TYPE) imageFileSize = it.getInt(FilePickerConst.EXTRA_IMAGE_FILE_SIZE) videoFileSize = it.getInt(FilePickerConst.EXTRA_VIDEO_FILE_SIZE) activity?.let { @@ -102,7 +107,8 @@ class MediaDetailPickerFragment : BaseFragment(), FileAdapterListener { } val spanCount = PickerManager.spanTypes[FilePickerConst.SPAN_TYPE.DETAIL_SPAN] ?: 3 val layoutManager = StaggeredGridLayoutManager(spanCount, OrientationHelper.VERTICAL) - layoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS + layoutManager.gapStrategy = + StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS recyclerView.layoutManager = layoutManager recyclerView.itemAnimator = DefaultItemAnimator() @@ -130,10 +136,18 @@ class MediaDetailPickerFragment : BaseFragment(), FileAdapterListener { }) viewModel.lvDataChanged.observe(viewLifecycleOwner, Observer { - viewModel.getMedia(mediaType = fileType, imageFileSize = imageFileSize, videoFileSize = videoFileSize) + viewModel.getMedia( + mediaType = fileType, + imageFileSize = imageFileSize, + videoFileSize = videoFileSize + ) }) - viewModel.getMedia(mediaType = fileType, imageFileSize = imageFileSize, videoFileSize = videoFileSize) + viewModel.getMedia( + mediaType = fileType, + imageFileSize = imageFileSize, + videoFileSize = videoFileSize + ) } private fun updateList(medias: List) { @@ -148,16 +162,31 @@ class MediaDetailPickerFragment : BaseFragment(), FileAdapterListener { if (photoGridAdapter != null) { photoGridAdapter?.setData(medias, PickerManager.selectedPhotos) } else { - photoGridAdapter = PhotoGridAdapter(it, mGlideRequestManager, medias, PickerManager.selectedPhotos, fileType == FilePickerConst.MEDIA_TYPE_IMAGE && PickerManager.isEnableCamera, this) + photoGridAdapter = PhotoGridAdapter( + it, + mGlideRequestManager, + medias, + PickerManager.selectedPhotos, + fileType == FilePickerConst.MEDIA_TYPE_IMAGE && PickerManager.isEnableCamera, + this + ) recyclerView.adapter = photoGridAdapter photoGridAdapter?.setCameraListener(View.OnClickListener { try { uiScope.launch { - val intent = withContext(Dispatchers.IO) { imageCaptureManager?.dispatchTakePictureIntent() } + val intent = + withContext(Dispatchers.IO) { imageCaptureManager?.dispatchTakePictureIntent() } if (intent != null) - startActivityForResult(intent, ImageCaptureManager.REQUEST_TAKE_PHOTO) + startActivityForResult( + intent, + ImageCaptureManager.REQUEST_TAKE_PHOTO + ) else - Toast.makeText(activity, R.string.no_camera_exists, Toast.LENGTH_SHORT).show() + Toast.makeText( + activity, + R.string.no_camera_exists, + Toast.LENGTH_SHORT + ).show() } } catch (e: IOException) { e.printStackTrace() @@ -233,10 +262,14 @@ class MediaDetailPickerFragment : BaseFragment(), FileAdapterListener { private val TAG = MediaDetailPickerFragment::class.java.simpleName private val SCROLL_THRESHOLD = 30 - fun newInstance(fileType: Int, imageFileSize: Int, videoFileSize: Int): MediaDetailPickerFragment { + fun newInstance( + fileType: Int, + imageFileSize: Int, + videoFileSize: Int + ): MediaDetailPickerFragment { val mediaDetailPickerFragment = MediaDetailPickerFragment() val bun = Bundle() - bun.putInt(BaseFragment.Companion.FILE_TYPE, fileType) + bun.putInt(FILE_TYPE, fileType) bun.putInt(FilePickerConst.EXTRA_IMAGE_FILE_SIZE, imageFileSize) bun.putInt(FilePickerConst.EXTRA_VIDEO_FILE_SIZE, videoFileSize) mediaDetailPickerFragment.arguments = bun diff --git a/filepicker/src/main/java/droidninja/filepicker/fragments/MediaFolderPickerFragment.kt b/filepicker/src/main/java/droidninja/filepicker/fragments/MediaFolderPickerFragment.kt index 78c960f..7895e86 100644 --- a/filepicker/src/main/java/droidninja/filepicker/fragments/MediaFolderPickerFragment.kt +++ b/filepicker/src/main/java/droidninja/filepicker/fragments/MediaFolderPickerFragment.kt @@ -4,9 +4,6 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle -import androidx.recyclerview.widget.DefaultItemAnimator -import androidx.recyclerview.widget.GridLayoutManager -import androidx.recyclerview.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -14,6 +11,9 @@ import android.widget.TextView import android.widget.Toast import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.RequestManager import droidninja.filepicker.FilePickerConst @@ -45,8 +45,10 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd private var imageFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE private var videoFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_media_folder_picker, container, false) } @@ -57,7 +59,8 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd mListener = context } else { throw RuntimeException( - "$context must implement PhotoPickerFragmentListener") + "$context must implement PhotoPickerFragmentListener" + ) } } @@ -69,7 +72,10 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mGlideRequestManager = Glide.with(this) - viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(requireActivity().application)).get(VMMediaPicker::class.java) + viewModel = ViewModelProvider( + this, + ViewModelProvider.AndroidViewModelFactory(requireActivity().application) + ).get(VMMediaPicker::class.java) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -81,18 +87,25 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd recyclerView = view.findViewById(R.id.recyclerview) emptyView = view.findViewById(R.id.empty_view) arguments?.let { - fileType = it.getInt(BaseFragment.FILE_TYPE) + fileType = it.getInt(FILE_TYPE) imageFileSize = it.getInt(FilePickerConst.EXTRA_IMAGE_FILE_SIZE) videoFileSize = it.getInt(FilePickerConst.EXTRA_VIDEO_FILE_SIZE) fileType = it.getInt(FILE_TYPE) imageCaptureManager = ImageCaptureManager(requireContext()) - val spanCount = PickerManager.spanTypes[FilePickerConst.SPAN_TYPE.FOLDER_SPAN] ?: 2// default 2 columns + val spanCount = PickerManager.spanTypes[FilePickerConst.SPAN_TYPE.FOLDER_SPAN] + ?: 2// default 2 columns val spacing = 5 // 5px val includeEdge = false val layoutManager = GridLayoutManager(activity, spanCount) - recyclerView.addItemDecoration(GridSpacingItemDecoration(spanCount, spacing, includeEdge)) + recyclerView.addItemDecoration( + GridSpacingItemDecoration( + spanCount, + spacing, + includeEdge + ) + ) recyclerView.layoutManager = layoutManager recyclerView.itemAnimator = DefaultItemAnimator() @@ -119,10 +132,18 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd }) viewModel.lvDataChanged.observe(viewLifecycleOwner, Observer { - viewModel.getPhotoDirs(mediaType = fileType, imageFileSize = imageFileSize, videoFileSize = videoFileSize) + viewModel.getPhotoDirs( + mediaType = fileType, + imageFileSize = imageFileSize, + videoFileSize = videoFileSize + ) }) - viewModel.getPhotoDirs(mediaType = fileType, imageFileSize = imageFileSize, videoFileSize = videoFileSize) + viewModel.getPhotoDirs( + mediaType = fileType, + imageFileSize = imageFileSize, + videoFileSize = videoFileSize + ) } } @@ -138,7 +159,12 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd } if (photoGridAdapter == null) { - photoGridAdapter = FolderGridAdapter(requireContext(), mGlideRequestManager, dirs, fileType == FilePickerConst.MEDIA_TYPE_IMAGE && PickerManager.isEnableCamera) + photoGridAdapter = FolderGridAdapter( + requireContext(), + mGlideRequestManager, + dirs, + fileType == FilePickerConst.MEDIA_TYPE_IMAGE && PickerManager.isEnableCamera + ) recyclerView.adapter = photoGridAdapter photoGridAdapter?.setFolderGridAdapterListener(this) } else { @@ -151,11 +177,13 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd override fun onCameraClicked() { try { uiScope.launch { - val intent = withContext(Dispatchers.IO) { imageCaptureManager?.dispatchTakePictureIntent() } + val intent = + withContext(Dispatchers.IO) { imageCaptureManager?.dispatchTakePictureIntent() } if (intent != null) { startActivityForResult(intent, ImageCaptureManager.REQUEST_TAKE_PHOTO) } else { - Toast.makeText(requireContext(), R.string.no_camera_exists, Toast.LENGTH_SHORT).show() + Toast.makeText(requireContext(), R.string.no_camera_exists, Toast.LENGTH_SHORT) + .show() } } } catch (e: IOException) { @@ -207,10 +235,14 @@ class MediaFolderPickerFragment : BaseFragment(), FolderGridAdapter.FolderGridAd private val TAG = MediaFolderPickerFragment::class.java.simpleName private const val SCROLL_THRESHOLD = 30 - fun newInstance(fileType: Int, imageFileSize: Int, videoFileSize: Int): MediaFolderPickerFragment { + fun newInstance( + fileType: Int, + imageFileSize: Int, + videoFileSize: Int + ): MediaFolderPickerFragment { val photoPickerFragment = MediaFolderPickerFragment() val bun = Bundle() - bun.putInt(BaseFragment.FILE_TYPE, fileType) + bun.putInt(FILE_TYPE, fileType) bun.putInt(FilePickerConst.EXTRA_IMAGE_FILE_SIZE, imageFileSize) bun.putInt(FilePickerConst.EXTRA_VIDEO_FILE_SIZE, videoFileSize) bun.putInt(FILE_TYPE, fileType) diff --git a/filepicker/src/main/java/droidninja/filepicker/fragments/MediaPickerFragment.kt b/filepicker/src/main/java/droidninja/filepicker/fragments/MediaPickerFragment.kt index 5ec1dd1..cd71455 100644 --- a/filepicker/src/main/java/droidninja/filepicker/fragments/MediaPickerFragment.kt +++ b/filepicker/src/main/java/droidninja/filepicker/fragments/MediaPickerFragment.kt @@ -2,11 +2,11 @@ package droidninja.filepicker.fragments import android.content.Context import android.os.Bundle -import com.google.android.material.tabs.TabLayout -import androidx.viewpager.widget.ViewPager import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.viewpager.widget.ViewPager +import com.google.android.material.tabs.TabLayout import droidninja.filepicker.FilePickerConst import droidninja.filepicker.PickerManager import droidninja.filepicker.R @@ -22,8 +22,10 @@ class MediaPickerFragment : BaseFragment() { private var mListener: MediaPickerFragmentListener? = null - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_media_picker, container, false) } @@ -59,17 +61,41 @@ class MediaPickerFragment : BaseFragment() { if (PickerManager.showImages()) { if (PickerManager.isShowFolderView) - adapter.addFragment(MediaFolderPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_IMAGE, PickerManager.imageFileSize, PickerManager.videoFileSize), getString(R.string.images)) + adapter.addFragment( + MediaFolderPickerFragment.newInstance( + FilePickerConst.MEDIA_TYPE_IMAGE, + PickerManager.imageFileSize, + PickerManager.videoFileSize + ), getString(R.string.images) + ) else - adapter.addFragment(MediaDetailPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_IMAGE, PickerManager.imageFileSize, PickerManager.videoFileSize), getString(R.string.images)) + adapter.addFragment( + MediaDetailPickerFragment.newInstance( + FilePickerConst.MEDIA_TYPE_IMAGE, + PickerManager.imageFileSize, + PickerManager.videoFileSize + ), getString(R.string.images) + ) } else tabLayout.visibility = View.GONE if (PickerManager.showVideo()) { if (PickerManager.isShowFolderView) - adapter.addFragment(MediaFolderPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_VIDEO, PickerManager.imageFileSize, PickerManager.videoFileSize), getString(R.string.videos)) + adapter.addFragment( + MediaFolderPickerFragment.newInstance( + FilePickerConst.MEDIA_TYPE_VIDEO, + PickerManager.imageFileSize, + PickerManager.videoFileSize + ), getString(R.string.videos) + ) else - adapter.addFragment(MediaDetailPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_VIDEO, PickerManager.imageFileSize, PickerManager.videoFileSize), getString(R.string.videos)) + adapter.addFragment( + MediaDetailPickerFragment.newInstance( + FilePickerConst.MEDIA_TYPE_VIDEO, + PickerManager.imageFileSize, + PickerManager.videoFileSize + ), getString(R.string.videos) + ) } else tabLayout.visibility = View.GONE diff --git a/filepicker/src/main/java/droidninja/filepicker/models/BaseFile.kt b/filepicker/src/main/java/droidninja/filepicker/models/BaseFile.kt index 16dd893..879b260 100644 --- a/filepicker/src/main/java/droidninja/filepicker/models/BaseFile.kt +++ b/filepicker/src/main/java/droidninja/filepicker/models/BaseFile.kt @@ -1,16 +1,15 @@ package droidninja.filepicker.models import android.net.Uri -import android.os.Parcel import android.os.Parcelable -import droidninja.filepicker.utils.FilePickerUtils.contains import kotlinx.android.parcel.Parcelize /** * Created by droidNinja on 29/07/16. */ @Parcelize -open class BaseFile(open var id: Long = 0, - open var name: String, - open var path: Uri +open class BaseFile( + open var id: Long = 0, + open var name: String, + open var path: Uri ) : Parcelable \ No newline at end of file diff --git a/filepicker/src/main/java/droidninja/filepicker/models/Document.kt b/filepicker/src/main/java/droidninja/filepicker/models/Document.kt index 0378530..5cb8f0a 100644 --- a/filepicker/src/main/java/droidninja/filepicker/models/Document.kt +++ b/filepicker/src/main/java/droidninja/filepicker/models/Document.kt @@ -4,10 +4,11 @@ import android.net.Uri import kotlinx.android.parcel.Parcelize @Parcelize -class Document @JvmOverloads constructor(override var id: Long = 0, - override var name: String, - override var path: Uri, - var mimeType: String? = null, - var size: String? = null, - var fileType: FileType? = null +class Document @JvmOverloads constructor( + override var id: Long = 0, + override var name: String, + override var path: Uri, + var mimeType: String? = null, + var size: String? = null, + var fileType: FileType? = null ) : BaseFile(id, name, path) \ No newline at end of file diff --git a/filepicker/src/main/java/droidninja/filepicker/models/FileType.kt b/filepicker/src/main/java/droidninja/filepicker/models/FileType.kt index ab0dfc3..ed0577a 100644 --- a/filepicker/src/main/java/droidninja/filepicker/models/FileType.kt +++ b/filepicker/src/main/java/droidninja/filepicker/models/FileType.kt @@ -8,9 +8,9 @@ import kotlinx.android.parcel.Parcelize * Created by droidNinja on 29/07/16. */ @Parcelize -class FileType constructor( - var title: String, - var extensions : Array, - @DrawableRes - var drawable: Int +class FileType( + var title: String, + var extensions: Array, + @DrawableRes + var drawable: Int ) : Parcelable \ No newline at end of file diff --git a/filepicker/src/main/java/droidninja/filepicker/models/Media.kt b/filepicker/src/main/java/droidninja/filepicker/models/Media.kt index a37cdf1..ca11499 100755 --- a/filepicker/src/main/java/droidninja/filepicker/models/Media.kt +++ b/filepicker/src/main/java/droidninja/filepicker/models/Media.kt @@ -1,15 +1,15 @@ package droidninja.filepicker.models import android.net.Uri -import android.os.Parcelable -import androidx.annotation.DrawableRes import kotlinx.android.parcel.Parcelize @Parcelize -class Media @JvmOverloads constructor(override var id: Long = 0, - override var name: String, - override var path: Uri, - var mediaType: Int = 0) : BaseFile(id, name, path) +class Media @JvmOverloads constructor( + override var id: Long = 0, + override var name: String, + override var path: Uri, + var mediaType: Int = 0 +) : BaseFile(id, name, path) diff --git a/filepicker/src/main/java/droidninja/filepicker/models/PhotoDirectory.kt b/filepicker/src/main/java/droidninja/filepicker/models/PhotoDirectory.kt index 994cd88..2642c2c 100755 --- a/filepicker/src/main/java/droidninja/filepicker/models/PhotoDirectory.kt +++ b/filepicker/src/main/java/droidninja/filepicker/models/PhotoDirectory.kt @@ -6,12 +6,12 @@ import kotlinx.android.parcel.Parcelize @Parcelize class PhotoDirectory( - var id: Long = 0, - var bucketId: String? = null, - private var coverPath: Uri? = null, - var name: String? = null, - var dateAdded: Long = 0, - val medias: MutableList = mutableListOf() + var id: Long = 0, + var bucketId: String? = null, + private var coverPath: Uri? = null, + var name: String? = null, + var dateAdded: Long = 0, + val medias: MutableList = mutableListOf() ) : Parcelable { fun getCoverPath(): Uri? { @@ -19,7 +19,7 @@ class PhotoDirectory( medias.size > 0 -> medias[0].path coverPath != null -> coverPath else -> null - }; + } } fun setCoverPath(coverPath: Uri?) { diff --git a/filepicker/src/main/java/droidninja/filepicker/models/sort/NameComparator.kt b/filepicker/src/main/java/droidninja/filepicker/models/sort/NameComparator.kt index 54829cb..fce290b 100644 --- a/filepicker/src/main/java/droidninja/filepicker/models/sort/NameComparator.kt +++ b/filepicker/src/main/java/droidninja/filepicker/models/sort/NameComparator.kt @@ -8,6 +8,7 @@ import java.util.* */ class NameComparator : Comparator { override fun compare(o1: Document, o2: Document): Int { - return o1.name.toLowerCase(Locale.getDefault()).compareTo(o2.name.toLowerCase(Locale.getDefault())) + return o1.name.toLowerCase(Locale.getDefault()) + .compareTo(o2.name.toLowerCase(Locale.getDefault())) } } \ No newline at end of file diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/AndroidLifecycleUtils.kt b/filepicker/src/main/java/droidninja/filepicker/utils/AndroidLifecycleUtils.kt index 0495146..2471b1d 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/AndroidLifecycleUtils.kt +++ b/filepicker/src/main/java/droidninja/filepicker/utils/AndroidLifecycleUtils.kt @@ -4,7 +4,6 @@ import android.app.Activity import android.content.Context import android.os.Build import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity object AndroidLifecycleUtils { fun canLoadImage(fragment: Fragment?): Boolean { @@ -35,7 +34,8 @@ object AndroidLifecycleUtils { return true } - val destroyed = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed + val destroyed = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed return !(destroyed || activity.isFinishing) diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/ContentUriUtils.kt b/filepicker/src/main/java/droidninja/filepicker/utils/ContentUriUtils.kt index ffb66ca..2c50b61 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/ContentUriUtils.kt +++ b/filepicker/src/main/java/droidninja/filepicker/utils/ContentUriUtils.kt @@ -21,7 +21,11 @@ object ContentUriUtils { var selection: String? = null var selectionArgs: Array? = null // Uri is different in versions after KITKAT (Android 4.4), we need to - if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.applicationContext, uri)) { + if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri( + context.applicationContext, + uri + ) + ) { if (isExternalStorageDocument(uri)) { val docId = DocumentsContract.getDocumentId(uri) val split = docId.split(":").toTypedArray() @@ -29,7 +33,8 @@ object ContentUriUtils { } else if (isDownloadsDocument(uri)) { val id = DocumentsContract.getDocumentId(uri) uri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id)) + Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id) + ) } else if (isMediaDocument(uri)) { val docId = DocumentsContract.getDocumentId(uri) val split = docId.split(":").toTypedArray() @@ -43,7 +48,7 @@ object ContentUriUtils { } selection = "_id=?" selectionArgs = arrayOf( - split[1] + split[1] ) } } @@ -52,10 +57,11 @@ object ContentUriUtils { return uri.lastPathSegment } val projection = arrayOf( - MediaStore.Images.Media.DATA + MediaStore.Images.Media.DATA ) try { - val cursor = context.contentResolver?.query(uri, projection, selection, selectionArgs, null) + val cursor = + context.contentResolver?.query(uri, projection, selection, selectionArgs, null) var path: String? = null if (cursor != null) { val column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/FilePickerUtils.kt b/filepicker/src/main/java/droidninja/filepicker/utils/FilePickerUtils.kt index b852243..838bec6 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/FilePickerUtils.kt +++ b/filepicker/src/main/java/droidninja/filepicker/utils/FilePickerUtils.kt @@ -1,12 +1,9 @@ package droidninja.filepicker.utils import android.content.ContentResolver -import android.content.Context -import android.content.Intent import android.database.ContentObserver import android.net.Uri import android.os.Handler -import android.text.TextUtils import android.webkit.MimeTypeMap import java.io.File @@ -27,7 +24,7 @@ object FilePickerUtils { fun contains(types: Array, mimeType: String?): Boolean { for (type in types) { - if(MimeTypeMap.getSingleton().getMimeTypeFromExtension(type) == mimeType){ + if (MimeTypeMap.getSingleton().getMimeTypeFromExtension(type) == mimeType) { return true } } @@ -36,8 +33,8 @@ object FilePickerUtils { } fun ContentResolver.registerObserver( - uri: Uri, - observer: (selfChange: Boolean) -> Unit + uri: Uri, + observer: (selfChange: Boolean) -> Unit ): ContentObserver { val contentObserver = object : ContentObserver(Handler()) { override fun onChange(selfChange: Boolean) { diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/FileUtils.kt b/filepicker/src/main/java/droidninja/filepicker/utils/FileUtils.kt index e32ae24..5cafdd1 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/FileUtils.kt +++ b/filepicker/src/main/java/droidninja/filepicker/utils/FileUtils.kt @@ -1,11 +1,8 @@ package droidninja.filepicker.utils import android.text.TextUtils - -import java.io.File - import droidninja.filepicker.FilePickerConst -import droidninja.filepicker.R +import java.io.File /** * Created by droidNinja on 08/03/17. diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/FragmentUtil.kt b/filepicker/src/main/java/droidninja/filepicker/utils/FragmentUtil.kt index 8514e36..be99898 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/FragmentUtil.kt +++ b/filepicker/src/main/java/droidninja/filepicker/utils/FragmentUtil.kt @@ -1,9 +1,7 @@ package droidninja.filepicker.utils -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentTransaction import androidx.appcompat.app.AppCompatActivity - +import androidx.fragment.app.Fragment import droidninja.filepicker.R import droidninja.filepicker.fragments.BaseFragment @@ -38,33 +36,33 @@ object FragmentUtil { fun removeFragment(activity: AppCompatActivity, fragment: BaseFragment) { activity.supportFragmentManager.beginTransaction() - .remove(fragment) - .commit() + .remove(fragment) + .commit() } fun showFragment(activity: AppCompatActivity, fragment: BaseFragment) { activity.supportFragmentManager.beginTransaction() - .show(fragment) - .commit() + .show(fragment) + .commit() } fun hideFragment(activity: AppCompatActivity, fragment: BaseFragment) { activity.supportFragmentManager.beginTransaction() - .hide(fragment) - .commit() + .hide(fragment) + .commit() } fun attachFragment(activity: AppCompatActivity, fragment: BaseFragment) { activity.supportFragmentManager.beginTransaction() - .attach(fragment) - .commit() + .attach(fragment) + .commit() } fun detachFragment(activity: AppCompatActivity, fragment: BaseFragment) { activity.supportFragmentManager.beginTransaction() - .detach(fragment) - .commit() + .detach(fragment) + .commit() } fun getFragmentByTag(appCompatActivity: AppCompatActivity, tag: String): Fragment? { diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/GridSpacingItemDecoration.kt b/filepicker/src/main/java/droidninja/filepicker/utils/GridSpacingItemDecoration.kt index cae5f84..57a58c9 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/GridSpacingItemDecoration.kt +++ b/filepicker/src/main/java/droidninja/filepicker/utils/GridSpacingItemDecoration.kt @@ -1,18 +1,29 @@ package droidninja.filepicker.utils import android.graphics.Rect -import androidx.recyclerview.widget.RecyclerView import android.view.View +import androidx.recyclerview.widget.RecyclerView -class GridSpacingItemDecoration(private val spanCount: Int, private val spacing: Int, private val includeEdge: Boolean) : RecyclerView.ItemDecoration() { +class GridSpacingItemDecoration( + private val spanCount: Int, + private val spacing: Int, + private val includeEdge: Boolean +) : RecyclerView.ItemDecoration() { - override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { val position = parent.getChildAdapterPosition(view) // item position val column = position % spanCount // item column if (includeEdge) { - outRect.left = spacing - column * spacing / spanCount // spacing - column * ((1f / spanCount) * spacing) - outRect.right = (column + 1) * spacing / spanCount // (column + 1) * ((1f / spanCount) * spacing) + outRect.left = + spacing - column * spacing / spanCount // spacing - column * ((1f / spanCount) * spacing) + outRect.right = + (column + 1) * spacing / spanCount // (column + 1) * ((1f / spanCount) * spacing) if (position < spanCount) { // top edge outRect.top = spacing @@ -20,7 +31,8 @@ class GridSpacingItemDecoration(private val spanCount: Int, private val spacing: outRect.bottom = spacing // item bottom } else { outRect.left = column * spacing / spanCount // column * ((1f / spanCount) * spacing) - outRect.right = spacing - (column + 1) * spacing / spanCount // spacing - (column + 1) * ((1f / spanCount) * spacing) + outRect.right = + spacing - (column + 1) * spacing / spanCount // spacing - (column + 1) * ((1f / spanCount) * spacing) if (position >= spanCount) { outRect.top = spacing // item top } diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/ImageCaptureManager.kt b/filepicker/src/main/java/droidninja/filepicker/utils/ImageCaptureManager.kt index b7f47f6..c15414d 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/ImageCaptureManager.kt +++ b/filepicker/src/main/java/droidninja/filepicker/utils/ImageCaptureManager.kt @@ -5,23 +5,9 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Build -import android.os.Bundle -import android.os.Environment import android.provider.MediaStore -import android.provider.Settings -import androidx.core.content.FileProvider -import android.text.TextUtils -import android.util.Log import androidx.annotation.WorkerThread - -import java.io.File -import java.io.FileNotFoundException import java.io.IOException -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale - -import droidninja.filepicker.PickerManager class ImageCaptureManager(private val mContext: Context) { @@ -36,7 +22,8 @@ class ImageCaptureManager(private val mContext: Context) { put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg") } - currentPhotoPath = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) + currentPhotoPath = + resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) return currentPhotoPath } @@ -64,8 +51,8 @@ class ImageCaptureManager(private val mContext: Context) { fun deleteContentUri(path: Uri?) { - if(path != null){ - mContext.contentResolver.delete(path, null , null) + if (path != null) { + mContext.contentResolver.delete(path, null, null) } } diff --git a/filepicker/src/main/java/droidninja/filepicker/utils/TabLayoutHelper.java b/filepicker/src/main/java/droidninja/filepicker/utils/TabLayoutHelper.java index f413f3f..cd87c80 100644 --- a/filepicker/src/main/java/droidninja/filepicker/utils/TabLayoutHelper.java +++ b/filepicker/src/main/java/droidninja/filepicker/utils/TabLayoutHelper.java @@ -17,15 +17,17 @@ package droidninja.filepicker.utils; import android.database.DataSetObserver; +import android.view.Gravity; +import android.view.View; +import android.widget.LinearLayout; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.material.tabs.TabLayout; -import androidx.viewpager.widget.PagerAdapter; import androidx.core.view.ViewCompat; +import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; -import android.view.Gravity; -import android.view.View; -import android.widget.LinearLayout; + +import com.google.android.material.tabs.TabLayout; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; @@ -122,6 +124,15 @@ public ViewPager getViewPager() { return mViewPager; } + /** + * Gets whether auto tab mode adjustment is enabled. + * + * @return True for enabled, otherwise false. + */ + public boolean isAutoAdjustTabModeEnabled() { + return mAutoAdjustTabMode; + } + /** * Sets auto tab mode adjustment enabled * @@ -140,15 +151,6 @@ public void setAutoAdjustTabModeEnabled(boolean enabled) { } } - /** - * Gets whether auto tab mode adjustment is enabled. - * - * @return True for enabled, otherwise false. - */ - public boolean isAutoAdjustTabModeEnabled() { - return mAutoAdjustTabMode; - } - /** * Sets {@link TabLayout.OnTabSelectedListener} * diff --git a/filepicker/src/main/java/droidninja/filepicker/viewmodels/BaseViewModel.kt b/filepicker/src/main/java/droidninja/filepicker/viewmodels/BaseViewModel.kt index 79c004b..307cc56 100644 --- a/filepicker/src/main/java/droidninja/filepicker/viewmodels/BaseViewModel.kt +++ b/filepicker/src/main/java/droidninja/filepicker/viewmodels/BaseViewModel.kt @@ -4,7 +4,6 @@ import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel import kotlinx.coroutines.* open class BaseViewModel(application: Application) : AndroidViewModel(application) { diff --git a/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMDocPicker.kt b/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMDocPicker.kt index 81f20e5..8574c3d 100644 --- a/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMDocPicker.kt +++ b/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMDocPicker.kt @@ -9,7 +9,6 @@ import android.text.TextUtils import androidx.annotation.WorkerThread import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import droidninja.filepicker.FilePickerConst import droidninja.filepicker.PickerManager import droidninja.filepicker.models.Document import droidninja.filepicker.models.FileType @@ -33,21 +32,33 @@ class VMDocPicker(application: Application) : BaseViewModel(application) { } @WorkerThread - suspend fun queryDocs(fileTypes: List, comparator: Comparator?): HashMap> { + suspend fun queryDocs( + fileTypes: List, + comparator: Comparator? + ): HashMap> { var data = HashMap>() withContext(Dispatchers.IO) { - val selection = ("${MediaStore.Files.FileColumns.MEDIA_TYPE}!=${MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE}" + - " AND ${MediaStore.Files.FileColumns.MEDIA_TYPE}!=${MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO}") - - val DOC_PROJECTION = arrayOf(MediaStore.Files.FileColumns._ID, - MediaStore.Files.FileColumns.DATA, - MediaStore.Files.FileColumns.MIME_TYPE, - MediaStore.Files.FileColumns.SIZE, - MediaStore.Files.FileColumns.DATE_ADDED, - MediaStore.Files.FileColumns.TITLE) - - val cursor = getApplication().contentResolver.query(MediaStore.Files.getContentUri("external"), DOC_PROJECTION, selection, null, MediaStore.Files.FileColumns.DATE_ADDED + " DESC") + val selection = + ("${MediaStore.Files.FileColumns.MEDIA_TYPE}!=${MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE}" + + " AND ${MediaStore.Files.FileColumns.MEDIA_TYPE}!=${MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO}") + + val DOC_PROJECTION = arrayOf( + MediaStore.Files.FileColumns._ID, + MediaStore.Files.FileColumns.DATA, + MediaStore.Files.FileColumns.MIME_TYPE, + MediaStore.Files.FileColumns.SIZE, + MediaStore.Files.FileColumns.DATE_ADDED, + MediaStore.Files.FileColumns.TITLE + ) + + val cursor = getApplication().contentResolver.query( + MediaStore.Files.getContentUri("external"), + DOC_PROJECTION, + selection, + null, + MediaStore.Files.FileColumns.DATE_ADDED + " DESC" + ) if (cursor != null) { data = createDocumentType(fileTypes, comparator, getDocumentFromCursor(cursor)) @@ -58,11 +69,20 @@ class VMDocPicker(application: Application) : BaseViewModel(application) { } @WorkerThread - private fun createDocumentType(fileTypes: List, comparator: Comparator?, documents: MutableList): HashMap> { + private fun createDocumentType( + fileTypes: List, + comparator: Comparator?, + documents: MutableList + ): HashMap> { val documentMap = HashMap>() for (fileType in fileTypes) { - val documentListFilteredByType = documents.filter { document -> FilePickerUtils.contains(fileType.extensions, document.mimeType) } + val documentListFilteredByType = documents.filter { document -> + FilePickerUtils.contains( + fileType.extensions, + document.mimeType + ) + } comparator?.let { documentListFilteredByType.sortedWith(comparator) @@ -81,29 +101,32 @@ class VMDocPicker(application: Application) : BaseViewModel(application) { val imageId = data.getLong(data.getColumnIndexOrThrow(BaseColumns._ID)) val path = data.getString(data.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)) - val title = data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.TITLE)) + val title = + data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.TITLE)) if (path != null) { val fileType = getFileType(PickerManager.getFileTypes(), path) val file = File(path) val contentUri = ContentUris.withAppendedId( - MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), - imageId + MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), + imageId ) if (fileType != null && !file.isDirectory && file.exists()) { val document = Document(imageId, title, contentUri) document.fileType = fileType - val mimeType = data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE)) + val mimeType = + data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE)) if (mimeType != null && !TextUtils.isEmpty(mimeType)) { document.mimeType = mimeType } else { document.mimeType = "" } - document.size = data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)) + document.size = + data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)) if (!documents.contains(document)) documents.add(document) } diff --git a/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMMediaPicker.kt b/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMMediaPicker.kt index 37c2504..c17df8a 100644 --- a/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMMediaPicker.kt +++ b/filepicker/src/main/java/droidninja/filepicker/viewmodels/VMMediaPicker.kt @@ -39,14 +39,19 @@ class VMMediaPicker(application: Application) : BaseViewModel(application) { private fun registerContentObserver() { if (contentObserver == null) { contentObserver = getApplication().contentResolver.registerObserver( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI + MediaStore.Images.Media.EXTERNAL_CONTENT_URI ) { _lvDataChanged.value = true } } } - fun getMedia(bucketId: String? = null, mediaType: Int = FilePickerConst.MEDIA_TYPE_IMAGE, imageFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE, videoFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE) { + fun getMedia( + bucketId: String? = null, + mediaType: Int = FilePickerConst.MEDIA_TYPE_IMAGE, + imageFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE, + videoFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE + ) { launchDataLoad { val medias = mutableListOf() queryImages(bucketId, mediaType, imageFileSize, videoFileSize).map { dir -> @@ -59,7 +64,12 @@ class VMMediaPicker(application: Application) : BaseViewModel(application) { } } - fun getPhotoDirs(bucketId: String? = null, mediaType: Int = FilePickerConst.MEDIA_TYPE_IMAGE, imageFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE, videoFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE) { + fun getPhotoDirs( + bucketId: String? = null, + mediaType: Int = FilePickerConst.MEDIA_TYPE_IMAGE, + imageFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE, + videoFileSize: Int = FilePickerConst.DEFAULT_FILE_SIZE + ) { launchDataLoad { val dirs = queryImages(bucketId, mediaType, imageFileSize, videoFileSize) val photoDirectory = PhotoDirectory() @@ -67,13 +77,18 @@ class VMMediaPicker(application: Application) : BaseViewModel(application) { when (mediaType) { FilePickerConst.MEDIA_TYPE_VIDEO -> { - photoDirectory.name = getApplication().applicationContext.getString(R.string.all_videos) + photoDirectory.name = + getApplication().applicationContext.getString(R.string.all_videos) } + FilePickerConst.MEDIA_TYPE_IMAGE -> { - photoDirectory.name = getApplication().applicationContext.getString(R.string.all_photos) + photoDirectory.name = + getApplication().applicationContext.getString(R.string.all_photos) } + else -> { - photoDirectory.name = getApplication().applicationContext.getString(R.string.all_files) + photoDirectory.name = + getApplication().applicationContext.getString(R.string.all_files) } } @@ -93,7 +108,12 @@ class VMMediaPicker(application: Application) : BaseViewModel(application) { } @WorkerThread - suspend fun queryImages(bucketId: String?, mediaType: Int, imageFileSize: Int, videoFileSize: Int): MutableList { + suspend fun queryImages( + bucketId: String?, + mediaType: Int, + imageFileSize: Int, + videoFileSize: Int + ): MutableList { var data = mutableListOf() withContext(Dispatchers.IO) { val projection = null @@ -120,13 +140,20 @@ class VMMediaPicker(application: Application) : BaseViewModel(application) { } if (!PickerManager.isShowGif) { - selection += " AND " + MediaStore.Images.Media.MIME_TYPE + "!='" + MimeTypeMap.getSingleton().getMimeTypeFromExtension("gif") + "'" + selection += " AND " + MediaStore.Images.Media.MIME_TYPE + "!='" + MimeTypeMap.getSingleton() + .getMimeTypeFromExtension("gif") + "'" } if (bucketId != null) selection += " AND " + MediaStore.Images.Media.BUCKET_ID + "='" + bucketId + "'" - val cursor = getApplication().contentResolver.query(uri, projection, selection, selectionArgs.toTypedArray(), sortOrder) + val cursor = getApplication().contentResolver.query( + uri, + projection, + selection, + selectionArgs.toTypedArray(), + sortOrder + ) if (cursor != null) { data = getPhotoDirectories(mediaType, cursor) @@ -143,10 +170,13 @@ class VMMediaPicker(application: Application) : BaseViewModel(application) { while (data.moveToNext()) { val imageId = data.getLong(data.getColumnIndexOrThrow(BaseColumns._ID)) - val bucketId = data.getString(data.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.BUCKET_ID)) - val name = data.getString(data.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME)) + val bucketId = + data.getString(data.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.BUCKET_ID)) + val name = + data.getString(data.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME)) val fileName = data.getString(data.getColumnIndexOrThrow(MediaStore.MediaColumns.TITLE)) - val mediaType = data.getInt(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE)) + val mediaType = + data.getInt(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE)) val photoDirectory = PhotoDirectory() photoDirectory.id = imageId @@ -154,22 +184,23 @@ class VMMediaPicker(application: Application) : BaseViewModel(application) { photoDirectory.name = name var contentUri = ContentUris.withAppendedId( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - imageId + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + imageId ) if (fileType == FilePickerConst.MEDIA_TYPE_VIDEO) { contentUri = ContentUris.withAppendedId( - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - imageId + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + imageId ) } if (!directories.contains(photoDirectory)) { photoDirectory.addPhoto(imageId, fileName, contentUri, mediaType) - photoDirectory.dateAdded = data.getLong(data.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_ADDED)) + photoDirectory.dateAdded = + data.getLong(data.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_ADDED)) directories.add(photoDirectory) } else { directories[directories.indexOf(photoDirectory)] - .addPhoto(imageId, fileName, contentUri, mediaType) + .addPhoto(imageId, fileName, contentUri, mediaType) } } diff --git a/filepicker/src/main/java/droidninja/filepicker/views/SmoothCheckBox.kt b/filepicker/src/main/java/droidninja/filepicker/views/SmoothCheckBox.kt index 1a1ed5f..c52edcf 100644 --- a/filepicker/src/main/java/droidninja/filepicker/views/SmoothCheckBox.kt +++ b/filepicker/src/main/java/droidninja/filepicker/views/SmoothCheckBox.kt @@ -3,7 +3,6 @@ package droidninja.filepicker.views import android.animation.ValueAnimator import android.annotation.TargetApi import android.content.Context -import android.content.res.TypedArray import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint @@ -16,7 +15,6 @@ import android.util.AttributeSet import android.view.View import android.view.animation.LinearInterpolator import android.widget.Checkable - import droidninja.filepicker.R @@ -44,12 +42,22 @@ class SmoothCheckBox : View, Checkable { private var mTickDrawing: Boolean = false private var mListener: OnCheckedChangeListener? = null - @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context, attrs, defStyleAttr) { + @JvmOverloads + constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super( + context, + attrs, + defStyleAttr + ) { init(attrs) } @TargetApi(Build.VERSION_CODES.LOLLIPOP) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) { + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super( + context, + attrs, + defStyleAttr, + defStyleRes + ) { init(attrs) } @@ -58,11 +66,14 @@ class SmoothCheckBox : View, Checkable { val ta = context.obtainStyledAttributes(attrs, R.styleable.SmoothCheckBox) val tickColor = ta.getColor(R.styleable.SmoothCheckBox_color_tick, COLOR_TICK) mAnimDuration = ta.getInt(R.styleable.SmoothCheckBox_duration, DEF_ANIM_DURATION) - mFloorColor = ta.getColor(R.styleable.SmoothCheckBox_color_unchecked_stroke, COLOR_FLOOR_UNCHECKED) + mFloorColor = + ta.getColor(R.styleable.SmoothCheckBox_color_unchecked_stroke, COLOR_FLOOR_UNCHECKED) mCheckedColor = ta.getColor(R.styleable.SmoothCheckBox_color_checked, COLOR_CHECKED) mUnCheckedColor = ta.getColor(R.styleable.SmoothCheckBox_color_unchecked, COLOR_UNCHECKED) - mStrokeWidth = ta.getDimensionPixelSize(R.styleable.SmoothCheckBox_stroke_width, - dp2px(context, 0f)) + mStrokeWidth = ta.getDimensionPixelSize( + R.styleable.SmoothCheckBox_stroke_width, + dp2px(context, 0f) + ) ta.recycle() mFloorUnCheckedColor = mFloorColor @@ -81,7 +92,7 @@ class SmoothCheckBox : View, Checkable { mTickPath = Path() mCenterPoint = Point() - mTickPoints = arrayOf(Point(),Point(),Point()) + mTickPoints = arrayOf(Point(), Point(), Point()) setOnClickListener { toggle() @@ -164,13 +175,15 @@ class SmoothCheckBox : View, Checkable { private fun measureSize(measureSpec: Int): Int { val defSize = dp2px(context, DEF_DRAW_SIZE.toFloat()) - val specSize = View.MeasureSpec.getSize(measureSpec) - val specMode = View.MeasureSpec.getMode(measureSpec) + val specSize = MeasureSpec.getSize(measureSpec) + val specMode = MeasureSpec.getMode(measureSpec) var result = 0 when (specMode) { - View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.AT_MOST -> result = Math.min(defSize, specSize) - View.MeasureSpec.EXACTLY -> result = specSize + MeasureSpec.UNSPECIFIED, MeasureSpec.AT_MOST -> result = + Math.min(defSize, specSize) + + MeasureSpec.EXACTLY -> result = specSize } return result } @@ -195,8 +208,18 @@ class SmoothCheckBox : View, Checkable { mTickPoints!![2].x = Math.round(measuredWidth.toFloat() / 30 * 22) mTickPoints!![2].y = Math.round(measuredHeight.toFloat() / 30 * 10) - mLeftLineDistance = Math.sqrt(Math.pow((mTickPoints!![1].x - mTickPoints!![0].x).toDouble(), 2.0) + Math.pow((mTickPoints!![1].y - mTickPoints!![0].y).toDouble(), 2.0)).toFloat() - mRightLineDistance = Math.sqrt(Math.pow((mTickPoints!![2].x - mTickPoints!![1].x).toDouble(), 2.0) + Math.pow((mTickPoints!![2].y - mTickPoints!![1].y).toDouble(), 2.0)).toFloat() + mLeftLineDistance = Math.sqrt( + Math.pow( + (mTickPoints!![1].x - mTickPoints!![0].x).toDouble(), + 2.0 + ) + Math.pow((mTickPoints!![1].y - mTickPoints!![0].y).toDouble(), 2.0) + ).toFloat() + mRightLineDistance = Math.sqrt( + Math.pow( + (mTickPoints!![2].x - mTickPoints!![1].x).toDouble(), + 2.0 + ) + Math.pow((mTickPoints!![2].y - mTickPoints!![1].y).toDouble(), 2.0) + ).toFloat() mTickPaint!!.strokeWidth = mStrokeWidth.toFloat() } @@ -215,7 +238,12 @@ class SmoothCheckBox : View, Checkable { private fun drawBorder(canvas: Canvas) { mFloorPaint!!.color = mFloorColor val radius = mCenterPoint!!.x - canvas.drawCircle(mCenterPoint!!.x.toFloat(), mCenterPoint!!.y.toFloat(), radius * mFloorScale, mFloorPaint!!) + canvas.drawCircle( + mCenterPoint!!.x.toFloat(), + mCenterPoint!!.y.toFloat(), + radius * mFloorScale, + mFloorPaint!! + ) } private fun drawTick(canvas: Canvas) { @@ -230,8 +258,10 @@ class SmoothCheckBox : View, Checkable { if (mDrewDistance < mLeftLineDistance) { val step = if (mWidth / 20.0f < 3) 3f else mWidth / 20.0f mDrewDistance += step - val stopX = mTickPoints!![0].x + (mTickPoints!![1].x - mTickPoints!![0].x) * mDrewDistance / mLeftLineDistance - val stopY = mTickPoints!![0].y + (mTickPoints!![1].y - mTickPoints!![0].y) * mDrewDistance / mLeftLineDistance + val stopX = + mTickPoints!![0].x + (mTickPoints!![1].x - mTickPoints!![0].x) * mDrewDistance / mLeftLineDistance + val stopY = + mTickPoints!![0].y + (mTickPoints!![1].y - mTickPoints!![0].y) * mDrewDistance / mLeftLineDistance mTickPath!!.moveTo(mTickPoints!![0].x.toFloat(), mTickPoints!![0].y.toFloat()) mTickPath!!.lineTo(stopX, stopY) @@ -248,8 +278,10 @@ class SmoothCheckBox : View, Checkable { // draw right of the tick if (mDrewDistance < mLeftLineDistance + mRightLineDistance) { - val stopX = mTickPoints!![1].x + (mTickPoints!![2].x - mTickPoints!![1].x) * (mDrewDistance - mLeftLineDistance) / mRightLineDistance - val stopY = mTickPoints!![1].y - (mTickPoints!![1].y - mTickPoints!![2].y) * (mDrewDistance - mLeftLineDistance) / mRightLineDistance + val stopX = + mTickPoints!![1].x + (mTickPoints!![2].x - mTickPoints!![1].x) * (mDrewDistance - mLeftLineDistance) / mRightLineDistance + val stopY = + mTickPoints!![1].y - (mTickPoints!![1].y - mTickPoints!![2].y) * (mDrewDistance - mLeftLineDistance) / mRightLineDistance mTickPath!!.reset() mTickPath!!.moveTo(mTickPoints!![1].x.toFloat(), mTickPoints!![1].y.toFloat()) diff --git a/filepicker/src/main/java/droidninja/filepicker/views/SquareRelativeLayout.kt b/filepicker/src/main/java/droidninja/filepicker/views/SquareRelativeLayout.kt index a1ddb6e..6f0ad05 100644 --- a/filepicker/src/main/java/droidninja/filepicker/views/SquareRelativeLayout.kt +++ b/filepicker/src/main/java/droidninja/filepicker/views/SquareRelativeLayout.kt @@ -10,15 +10,23 @@ import android.widget.RelativeLayout * where the height is based off the width. */ class SquareRelativeLayout : RelativeLayout { - constructor(context: Context) : super(context) {} + constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) @TargetApi(Build.VERSION_CODES.LOLLIPOP) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) { - } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super( + context, + attrs, + defStyleAttr, + defStyleRes + ) override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { // Set getBitmap square layout. diff --git a/gradle.properties b/gradle.properties index 915f0e6..65279e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,4 +17,6 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true android.enableJetifier=true +android.nonFinalResIds=false +android.nonTransitiveRClass=false android.useAndroidX=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0320854..256fef6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Jun 05 19:09:53 MYT 2024 +#Tue Oct 29 15:19:04 MYT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists