Commit 87ede196 authored by Bartek Fabiszewski's avatar Bartek Fabiszewski
Browse files

Don't store thumbnail in state bundle

parent 431d1b58
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -171,7 +171,7 @@ class ImageHelper {
        int sizePx = getThumbnailSize(context);
        Bitmap bitmap;
        ContentResolver cr = context.getContentResolver();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        if (uri.getScheme().equals("content") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            bitmap = cr.loadThumbnail(uri, new Size(sizePx, sizePx), null);
        } else {
            try (InputStream is = cr.openInputStream(uri)) {
@@ -185,9 +185,9 @@ class ImageHelper {
    }

    /**
     * Extract thumbnail from URI
     * Extract thumbnail from bitmap
     * @param context Context
     * @param uri URI
     * @param bitmap Bitmap
     * @return Thumbnail
     */
    static Bitmap getThumbnail(@NonNull Context context, @NonNull Bitmap bitmap) {
+20 −8
Original line number Diff line number Diff line
@@ -47,12 +47,18 @@ class ImageTask implements Runnable {

    private boolean isRunning = false;
    private boolean isCancelled = false;
    private final boolean onlyThumbnail;

    private final Handler uiHandler = new Handler(Looper.getMainLooper());

    ImageTask(Uri uri, ImageTaskCallback callback) {
        this(uri, callback, false);
    }

    ImageTask(Uri uri, ImageTaskCallback callback, boolean onlyThumbnail) {
        this.uri = uri;
        weakCallback = new WeakReference<>(callback);
        this.onlyThumbnail = onlyThumbnail;
    }

    @Override
@@ -83,11 +89,16 @@ class ImageTask implements Runnable {
        if (activity == null) {
            return null;
        }

        ImageTaskResult result = null;
        try {
            Uri savedUri;
            Bitmap thumbnail;

            if (onlyThumbnail) {
                savedUri = uri;
                thumbnail = getThumbnail(activity, uri);
            } else {
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
                int dstWidth = Integer.parseInt(prefs.getString(SettingsActivity.KEY_IMAGE_SIZE, activity.getString(R.string.pref_imagesize_default)));
                if (dstWidth == 0) {
@@ -100,6 +111,7 @@ class ImageTask implements Runnable {
                    thumbnail = getThumbnail(activity, bitmap);
                    bitmap.recycle();
                }
            }
            if (savedUri != null && thumbnail != null) {
                result = new ImageTaskResult(savedUri, thumbnail);
            }
+98 −68
Original line number Diff line number Diff line
@@ -53,8 +53,8 @@ import java.util.concurrent.ExecutorService;
public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskCallback, ImageTask.ImageTaskCallback {

    private static final String KEY_URI = "keyPhotoUri";
    private static final String KEY_THUMB = "keyPhotoThumb";
    private static final String KEY_LOCATION = "keyLocation";
    private static final String KEY_WAITING = "keyWaiting";

    private static final String TAG = WaypointFragment.class.getSimpleName();

@@ -72,9 +72,74 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC
    private Location location = null;
    private Uri photoUri = null;
    private Bitmap photoThumb = null;
    private boolean isWaitingForCamera = false;

    private final ExecutorService executor = newCachedThreadPool();

    /**
     * Request location permission(s), on granted run logger task
     */
    final ActivityResultLauncher<String[]> requestLocationPermission = registerForActivityResult(new RequestMultiplePermissions(), results -> {
        if (Logger.DEBUG) { Log.d(TAG, "[requestLocationPermission: " + results.entrySet() + "]"); }
        boolean isGranted = false;
        for (Map.Entry<String, Boolean> result : results.entrySet()) {
            if (result.getValue()) {
                isGranted = true;
            }
        }
        if (isGranted) {
            if (Logger.DEBUG) { Log.d(TAG, "[LocationPermission: granted]"); }
            runLoggerTask();
        } else {
            if (Logger.DEBUG) { Log.d(TAG, "[LocationPermission: refused]"); }
            finish();
        }
    });

    /**
     * Request write permission, on granted take picture
     */
    final ActivityResultLauncher<String> requestWritePermission = registerForActivityResult(new RequestPermission(), isGranted -> {
        if (Logger.DEBUG) { Log.d(TAG, "[requestWritePermission: " + isGranted + "]"); }
        if (isGranted) {
            requestImageCapture();
        }
    });

    /**
     * Take picture, then run image task
     */
    final ActivityResultLauncher<Uri> takePicture = registerForActivityResult(new TakePicture() {
        @NonNull
        @Override
        public Intent createIntent(@NonNull Context context, @NonNull Uri input) {
            isWaitingForCamera = true;
            int flags = FLAG_GRANT_WRITE_URI_PERMISSION|FLAG_GRANT_READ_URI_PERMISSION|FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
            return super.createIntent(context, input).addFlags(flags);
        }
    }, isSaved -> {
        if (Logger.DEBUG) { Log.d(TAG, "[TakePicture result]"); }
        if (isSaved) {
            if (photoUri != null) {
                ImageHelper.galleryAdd(requireContext(), photoUri);
                runImageTask(photoUri);
            }
        } else {
            clearImage();
        }
        isWaitingForCamera = false;
    });

    /**
     * Open image file, then run image task
     */
    final ActivityResultLauncher<String[]> openPicture = registerForActivityResult(new OpenLocalDocument(), uri -> {
        if (uri != null) {
            photoUri = uri;
            runImageTask(photoUri);
        }
    });

    public WaypointFragment() { }

    static WaypointFragment newInstance() {
@@ -84,13 +149,13 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //noinspection deprecation
        setRetainInstance(true);
        if (Logger.DEBUG) { Log.d(TAG, "[onCreate]"); }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (Logger.DEBUG) { Log.d(TAG, "[onCreateView]"); }
        View layout = inflater.inflate(R.layout.fragment_waypoint, container, false);

        locationNotFoundTextView = layout.findViewById(R.id.waypointLocationNotFound);
@@ -111,13 +176,12 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC
    }

    private void restoreState(Bundle savedInstanceState) {
        if (Logger.DEBUG) { Log.d(TAG, "[restoreState]"); }
        if (savedInstanceState.containsKey(KEY_WAITING)) {
            isWaitingForCamera = true;
        }
        if (savedInstanceState.containsKey(KEY_URI)) {
            photoUri = savedInstanceState.getParcelable(KEY_URI);
            setThumbnail(photoThumb);
        }
        if (savedInstanceState.containsKey(KEY_THUMB)) {
            photoThumb = savedInstanceState.getParcelable(KEY_THUMB);
            setThumbnail(photoThumb);
        }
        if (savedInstanceState.containsKey(KEY_LOCATION)) {
            location = savedInstanceState.getParcelable(KEY_LOCATION);
@@ -134,23 +198,28 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC
    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        if (Logger.DEBUG) { Log.d(TAG, "[onSaveInstanceState]"); }
        if (photoUri != null) {
            outState.putParcelable(KEY_URI, photoUri);
        }
        if (photoThumb != null) {
            outState.putParcelable(KEY_THUMB, photoThumb);
        }
        if (location != null) {
            outState.putParcelable(KEY_LOCATION, location);
        }
        if (isWaitingForCamera) {
            outState.putBoolean(KEY_WAITING, true);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (Logger.DEBUG) { Log.d(TAG, "[onResume]"); }
        if (!hasLocation()) {
            runLoggerTask();
        }
        if (photoUri != null && photoThumb == null && !isWaitingForCamera) {
            runThumbnailTask(photoUri);
        }
    }

    /**
@@ -196,9 +265,12 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC

    /**
     * Start image task
     * Transforms image if needed and generates thumbnail for URI
     * @param uri URI
     */
    private void runImageTask(@NonNull Uri uri) {
        if (imageTask == null || !imageTask.isRunning()) {
            if (Logger.DEBUG) { Log.d(TAG, "[runImageTask]"); }
            clearImage();
            saveButton.setEnabled(false);
            imageTask = new ImageTask(uri, this);
@@ -207,6 +279,20 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC
        }
    }

    /**
     * Start thumbnail task
     * Generates thumbnail for URI
     * @param uri URI
     */
    private void runThumbnailTask(@NonNull Uri uri) {
        if (imageTask == null || !imageTask.isRunning()) {
            if (Logger.DEBUG) { Log.d(TAG, "[runThumbnailTask]"); }
            imageTask = new ImageTask(uri, this, true);
            executor.execute(imageTask);
            setRefreshing(true);
        }
    }

    private void setRefreshing(boolean refreshing) {
        swipe.setRefreshing(refreshing);
    }
@@ -214,6 +300,7 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC
    @Override
    public void onDetach() {
        super.onDetach();
        if (Logger.DEBUG) { Log.d(TAG, "[onDetach]"); }
        cancelLoggerTask();
        cancelImageTask();
    }
@@ -362,63 +449,6 @@ public class WaypointFragment extends Fragment implements LoggerTask.LoggerTaskC
        }
    }

    /**
     * Request location permission(s), on granted run logger task
     */
    final ActivityResultLauncher<String[]> requestLocationPermission = registerForActivityResult(new RequestMultiplePermissions(), results -> {
        if (Logger.DEBUG) { Log.d(TAG, "[requestLocationPermission: " + results.entrySet() + "]"); }
        boolean isGranted = false;
        for (Map.Entry<String, Boolean> result : results.entrySet()) {
            if (result.getValue()) {
                isGranted = true;
            }
        }
        if (isGranted) {
            if (Logger.DEBUG) { Log.d(TAG, "[LocationPermission: granted]"); }
            runLoggerTask();
        } else {
            if (Logger.DEBUG) { Log.d(TAG, "[LocationPermission: refused]"); }
            finish();
        }
    });

    /**
     * Request write permission, on granted take picture
     */
    final ActivityResultLauncher<String> requestWritePermission = registerForActivityResult(new RequestPermission(), isGranted -> {
        if (Logger.DEBUG) { Log.d(TAG, "[requestWritePermission: " + isGranted + "]"); }
        if (isGranted) {
            requestImageCapture();
        }
    });

    /**
     * Take picture, then run image task
     */
    final ActivityResultLauncher<Uri> takePicture = registerForActivityResult(new TakePicture() {
        @NonNull
        @Override
        public Intent createIntent(@NonNull Context context, @NonNull Uri input) {
            int flags = FLAG_GRANT_WRITE_URI_PERMISSION|FLAG_GRANT_READ_URI_PERMISSION|FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
            return super.createIntent(context, input).addFlags(flags);
        }
    }, isSaved -> {
        if (isSaved && photoUri != null) {
            ImageHelper.galleryAdd(requireContext(), photoUri);
            runImageTask(photoUri);
        }
    });

    /**
     * Open image file, then run image task
     */
    final ActivityResultLauncher<String[]> openPicture = registerForActivityResult(new OpenLocalDocument(), uri -> {
        if (uri != null) {
            photoUri = uri;
            runImageTask(photoUri);
        }
    });

    /**
     * Update state on location received
     * @param location Current location