Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-deck.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2020-11-05 10:18:27 +0300
committerStefan Niedermann <info@niedermann.it>2020-11-05 10:18:27 +0300
commit9f442181a8f1b405283b55df128ed4fa9dc6b42e (patch)
tree1facd03f9f8c08c98b64ae481db6fa0a37c9abb6 /app/src/main/java/it
parent92a96a57c36b69939dc860b74c9f9a84cdaa0372 (diff)
Check for closed cursors to prevent crashes when switchting quickly between adapter types
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main/java/it')
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java17
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/AbstractCursorPickerAdapter.java2
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/ContactAdapter.java (renamed from app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/ContactAdapterAbstract.java)42
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/FileAdapter.java18
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java (renamed from app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapterAbstract.java)4
5 files changed, 45 insertions, 38 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java
index eb7822679..b137b1b7f 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java
@@ -4,6 +4,7 @@ import android.animation.ValueAnimator;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -50,10 +51,10 @@ import it.niedermann.nextcloud.deck.ui.branding.BrandedFragment;
import it.niedermann.nextcloud.deck.ui.branding.BrandedSnackbar;
import it.niedermann.nextcloud.deck.ui.card.EditCardViewModel;
import it.niedermann.nextcloud.deck.ui.card.attachments.picker.AbstractPickerAdapter;
-import it.niedermann.nextcloud.deck.ui.card.attachments.picker.ContactAdapterAbstract;
+import it.niedermann.nextcloud.deck.ui.card.attachments.picker.ContactAdapter;
import it.niedermann.nextcloud.deck.ui.card.attachments.picker.FileAdapter;
import it.niedermann.nextcloud.deck.ui.card.attachments.picker.FileAdapterLegacy;
-import it.niedermann.nextcloud.deck.ui.card.attachments.picker.GalleryAdapterAbstract;
+import it.niedermann.nextcloud.deck.ui.card.attachments.picker.GalleryAdapter;
import it.niedermann.nextcloud.deck.ui.exception.ExceptionDialogFragment;
import it.niedermann.nextcloud.deck.ui.takephoto.TakePhotoActivity;
import it.niedermann.nextcloud.deck.util.VCardUtil;
@@ -264,7 +265,7 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
pickerAnimationInProgress = true;
binding.pickerBackdrop.setVisibility(VISIBLE);
binding.bottomNavigation.animate().translationY(0).setDuration(250).start();
- final ValueAnimator backdropAnimation = ValueAnimator.ofObject(ArgbEvaluatorCompat.getInstance(), getResources().getColor(android.R.color.transparent), getResources().getColor(R.color.mdtp_transparent_black));
+ final ValueAnimator backdropAnimation = ValueAnimator.ofObject(ArgbEvaluatorCompat.getInstance(), ((ColorDrawable) binding.pickerBackdrop.getBackground()).getColor(), getResources().getColor(R.color.mdtp_transparent_black));
backdropAnimation.setDuration(250);
backdropAnimation.addUpdateListener(animator -> binding.pickerBackdrop.setBackgroundColor((int) animator.getAnimatedValue()));
backdropAnimation.start();
@@ -274,7 +275,7 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
private void hidePickerSheet() {
pickerAnimationInProgress = true;
- final ValueAnimator backdropAnimation = ValueAnimator.ofObject(ArgbEvaluatorCompat.getInstance(), getResources().getColor(R.color.mdtp_transparent_black), getResources().getColor(android.R.color.transparent));
+ final ValueAnimator backdropAnimation = ValueAnimator.ofObject(ArgbEvaluatorCompat.getInstance(), ((ColorDrawable) binding.pickerBackdrop.getBackground()).getColor(), getResources().getColor(android.R.color.transparent));
backdropAnimation.setDuration(250);
backdropAnimation.addUpdateListener(animator -> binding.pickerBackdrop.setBackgroundColor((int) animator.getAnimatedValue()));
backdropAnimation.start();
@@ -287,12 +288,12 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
}
private void showGalleryPicker() {
- if (!(pickerAdapter instanceof GalleryAdapterAbstract)) {
+ if (!(pickerAdapter instanceof GalleryAdapter)) {
if (isPermissionRequestNeeded(READ_EXTERNAL_STORAGE) || isPermissionRequestNeeded(CAMERA)) {
requestPermissions(new String[]{READ_EXTERNAL_STORAGE, CAMERA}, REQUEST_CODE_PICK_GALLERY_PERMISSION);
} else {
unbindPickerAdapter();
- pickerAdapter = new GalleryAdapterAbstract(requireContext(), uri -> onActivityResult(REQUEST_CODE_PICK_FILE, RESULT_OK, new Intent().setData(uri)), this::openNativeCameraPicker, getViewLifecycleOwner());
+ pickerAdapter = new GalleryAdapter(requireContext(), uri -> onActivityResult(REQUEST_CODE_PICK_FILE, RESULT_OK, new Intent().setData(uri)), this::openNativeCameraPicker, getViewLifecycleOwner());
binding.pickerRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3));
binding.pickerRecyclerView.setAdapter(pickerAdapter);
}
@@ -300,12 +301,12 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
}
private void showContactPicker() {
- if (!(pickerAdapter instanceof ContactAdapterAbstract)) {
+ if (!(pickerAdapter instanceof ContactAdapter)) {
if (isPermissionRequestNeeded(READ_CONTACTS)) {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_CODE_PICK_CONTACT_PICKER_PERMISSION);
} else {
unbindPickerAdapter();
- pickerAdapter = new ContactAdapterAbstract(requireContext(), uri -> onActivityResult(REQUEST_CODE_PICK_CONTACT, RESULT_OK, new Intent().setData(uri)), this::openNativeContactPicker);
+ pickerAdapter = new ContactAdapter(requireContext(), uri -> onActivityResult(REQUEST_CODE_PICK_CONTACT, RESULT_OK, new Intent().setData(uri)), this::openNativeContactPicker);
binding.pickerRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
binding.pickerRecyclerView.setAdapter(pickerAdapter);
}
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/AbstractCursorPickerAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/AbstractCursorPickerAdapter.java
index 1890f5111..73058c757 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/AbstractCursorPickerAdapter.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/AbstractCursorPickerAdapter.java
@@ -69,7 +69,7 @@ public abstract class AbstractCursorPickerAdapter<T extends RecyclerView.ViewHol
*/
@Override
public long getItemId(int position) {
- if (cursor.moveToPosition(position - 1)) {
+ if (!cursor.isClosed() && cursor.moveToPosition(position - 1)) {
//noinspection SwitchStatementWithTooFewBranches
switch (columnIndexType) {
case FIELD_TYPE_INTEGER:
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/ContactAdapterAbstract.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/ContactAdapter.java
index b7b35dae5..874127103 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/ContactAdapterAbstract.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/ContactAdapter.java
@@ -31,13 +31,13 @@ import static android.provider.ContactsContract.Contacts.DISPLAY_NAME;
import static android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY;
import static android.provider.ContactsContract.Contacts._ID;
-public class ContactAdapterAbstract extends AbstractCursorPickerAdapter<RecyclerView.ViewHolder> {
+public class ContactAdapter extends AbstractCursorPickerAdapter<RecyclerView.ViewHolder> {
private final int lookupKeyColumnIndex;
private final int displayNameColumnIndex;
- public ContactAdapterAbstract(@NonNull Context context, @NonNull Consumer<Uri> onSelect, @NonNull Runnable onSelectPicker) {
+ public ContactAdapter(@NonNull Context context, @NonNull Consumer<Uri> onSelect, @NonNull Runnable onSelectPicker) {
super(context, onSelect, onSelectPicker, CONTENT_URI, _ID, new String[]{_ID, LOOKUP_KEY, DISPLAY_NAME}, SORT_KEY_PRIMARY);
lookupKeyColumnIndex = cursor.getColumnIndex(LOOKUP_KEY);
displayNameColumnIndex = cursor.getColumnIndex(DISPLAY_NAME);
@@ -67,27 +67,31 @@ public class ContactAdapterAbstract extends AbstractCursorPickerAdapter<Recycler
case VIEW_TYPE_ITEM: {
bindExecutor.execute(() -> {
final ContactItemViewHolder viewHolder = (ContactItemViewHolder) holder;
- cursor.moveToPosition(position - 1);
- final String displayName = cursor.getString(displayNameColumnIndex);
- final String lookupKey = cursor.getString(lookupKeyColumnIndex);
- try (InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, Uri.withAppendedPath(CONTENT_LOOKUP_URI, lookupKey))) {
- final Bitmap thumbnail = BitmapFactory.decodeStream(inputStream);
- String contactInformation = "";
- try (final Cursor phoneCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{NUMBER}, LOOKUP_KEY + " = ?", new String[]{lookupKey}, null)) {
- if (phoneCursor != null && phoneCursor.moveToFirst()) {
- contactInformation = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
+ if (!cursor.isClosed()) {
+ cursor.moveToPosition(position - 1);
+ final String displayName = cursor.getString(displayNameColumnIndex);
+ final String lookupKey = cursor.getString(lookupKeyColumnIndex);
+ try (InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, Uri.withAppendedPath(CONTENT_LOOKUP_URI, lookupKey))) {
+ final Bitmap thumbnail = BitmapFactory.decodeStream(inputStream);
+ String contactInformation = "";
+ try (final Cursor phoneCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{NUMBER}, LOOKUP_KEY + " = ?", new String[]{lookupKey}, null)) {
+ if (phoneCursor != null && phoneCursor.moveToFirst()) {
+ contactInformation = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
+ }
}
- }
- if (TextUtils.isEmpty(contactInformation)) {
- try (final Cursor emailCursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{DATA}, LOOKUP_KEY + " = ?", new String[]{lookupKey}, null)) {
- if (emailCursor != null && emailCursor.moveToFirst()) {
- contactInformation = emailCursor.getString(emailCursor.getColumnIndex(DATA));
+ if (TextUtils.isEmpty(contactInformation)) {
+ try (final Cursor emailCursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{DATA}, LOOKUP_KEY + " = ?", new String[]{lookupKey}, null)) {
+ if (emailCursor != null && emailCursor.moveToFirst()) {
+ contactInformation = emailCursor.getString(emailCursor.getColumnIndex(DATA));
+ }
}
}
+ final String finalContactInformation = contactInformation;
+ new Handler(Looper.getMainLooper()).post(() -> viewHolder.bind(Uri.withAppendedPath(CONTENT_LOOKUP_URI, lookupKey), thumbnail, displayName, finalContactInformation, onSelect));
+ } catch (IOException ignored) {
+ new Handler(Looper.getMainLooper()).post(viewHolder::bindError);
}
- final String finalContactInformation = contactInformation;
- new Handler(Looper.getMainLooper()).post(() -> viewHolder.bind(Uri.withAppendedPath(CONTENT_LOOKUP_URI, lookupKey), thumbnail, displayName, finalContactInformation, onSelect));
- } catch (IOException ignored) {
+ } else {
new Handler(Looper.getMainLooper()).post(viewHolder::bindError);
}
});
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/FileAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/FileAdapter.java
index 46e00fc95..47dd3f7a3 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/FileAdapter.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/FileAdapter.java
@@ -65,14 +65,16 @@ public class FileAdapter extends AbstractCursorPickerAdapter<RecyclerView.ViewHo
break;
}
case VIEW_TYPE_ITEM: {
- bindExecutor.execute(() -> {
- final long id = getItemId(position);
- final String name = cursor.getString(displayNameColumnIndex);
- final String mimeType = cursor.getString(mimeTypeColumnIndex);
- final long size = cursor.getLong(sizeColumnIndex);
- final long modified = cursor.getLong(modifiedColumnIndex);
- new Handler(Looper.getMainLooper()).post(() -> ((FileItemViewHolder) holder).bind(ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), id), name, mimeType, size, modified, onSelect));
- });
+ if (!cursor.isClosed()) {
+ bindExecutor.execute(() -> {
+ final long id = getItemId(position);
+ final String name = cursor.getString(displayNameColumnIndex);
+ final String mimeType = cursor.getString(mimeTypeColumnIndex);
+ final long size = cursor.getLong(sizeColumnIndex);
+ final long modified = cursor.getLong(modifiedColumnIndex);
+ new Handler(Looper.getMainLooper()).post(() -> ((FileItemViewHolder) holder).bind(ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), id), name, mimeType, size, modified, onSelect));
+ });
+ }
break;
}
}
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapterAbstract.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java
index d47187cd0..0be85d9e5 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapterAbstract.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java
@@ -27,7 +27,7 @@ import static android.os.Build.VERSION_CODES.Q;
import static android.provider.BaseColumns._ID;
import static android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-public class GalleryAdapterAbstract extends AbstractCursorPickerAdapter<RecyclerView.ViewHolder> {
+public class GalleryAdapter extends AbstractCursorPickerAdapter<RecyclerView.ViewHolder> {
@NonNull
private final LifecycleOwner lifecycleOwner;
@@ -37,7 +37,7 @@ public class GalleryAdapterAbstract extends AbstractCursorPickerAdapter<Recycler
? MediaStore.Images.Media.DATE_TAKEN
: MediaStore.Images.Media.DATE_ADDED;
- public GalleryAdapterAbstract(@NonNull Context context, @NonNull Consumer<Uri> onSelect, @NonNull Runnable openNativePicker, @NonNull LifecycleOwner lifecycleOwner) {
+ public GalleryAdapter(@NonNull Context context, @NonNull Consumer<Uri> onSelect, @NonNull Runnable openNativePicker, @NonNull LifecycleOwner lifecycleOwner) {
super(context, onSelect, openNativePicker, EXTERNAL_CONTENT_URI, _ID, sortOrder + " DESC");
this.lifecycleOwner = lifecycleOwner;
notifyItemRangeInserted(0, getItemCount());