com.cpjd.roblu.ui.images.ImageGalleryActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.cpjd.roblu.ui.images.ImageGalleryActivity.java

Source

package com.cpjd.roblu.ui.images;

import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.cpjd.roblu.R;
import com.cpjd.roblu.io.IO;
import com.cpjd.roblu.models.metrics.RGallery;
import com.cpjd.roblu.ui.team.TeamViewer;
import com.cpjd.roblu.utils.Constants;
import com.cpjd.roblu.utils.Utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import lombok.Setter;
import pub.devrel.easypermissions.EasyPermissions;

/**
 * Copyright 2015 Etienne Lawlor
 * Licensed under the Apache 2.0 License
 *
 * This activity will display a list of images.
 *
 * Accepted parameters:
 * -"eventID" - the ID of the event the gallery is contained in
 * -"galleryID" - the ID of the RGallery model
 * -"title" - what the title should be of this activity
 * -"editable" - true if the data should be editable (leave blank for a default of true)
 *
 *
 * Note: Images should be sent to the IMAGES array, not passed into this class. Intents have a payload maximum
 * that most images won't fit in, so use statics instead.
 *
 * Modifications were made to the original file to make this library compatible with Roblu.
 *
 */
public class ImageGalleryActivity extends AppCompatActivity implements ImageGalleryAdapter.OnImageClickListener,
        ImageGalleryAdapter.ImageThumbnailLoader, View.OnClickListener {

    private int eventID;
    private int rTabIndex;
    private int galleryID;

    /**
     * This is the image array that all the loaded images will be loaded from
     */
    public static ArrayList<byte[]> IMAGES;
    /**
     * Stores a temporary picture file before it's converted into a byte[] and serialized
     */
    private File tempPictureFile;

    private RecyclerView recyclerView;
    private RelativeLayout layout;
    private boolean editable;

    /*
     * Image loaders
     */
    @Setter
    private static ImageGalleryAdapter.ImageThumbnailLoader imageThumbnailLoader;
    private ImageGalleryAdapter imageGalleryAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_gallery);

        /*
         * Bind views
         */
        layout = findViewById(R.id.activity_image_gallery);
        recyclerView = findViewById(R.id.rv);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(this);

        // Receive data
        eventID = getIntent().getIntExtra("eventID", 0);
        galleryID = getIntent().getIntExtra("galleryID", 0);
        rTabIndex = getIntent().getIntExtra("rTabIndex", 0);

        editable = getIntent().getBooleanExtra("editable", true);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setTitle(getIntent().getStringExtra("title"));
        }

        setUpRecyclerView();
    }

    /**
     * Refreshes the recycler view UI
     */
    private void setUpRecyclerView() {
        /*
         * Setup the recycler adapter
         */
        int numOfColumns;
        if (Utils.isInLandscapeMode(this)) {
            numOfColumns = 4;
        } else {
            numOfColumns = 3;
        }

        recyclerView.setLayoutManager(new GridLayoutManager(ImageGalleryActivity.this, numOfColumns));
        imageGalleryAdapter = new ImageGalleryAdapter(getApplicationContext(), IMAGES);
        imageGalleryAdapter.setOnImageClickListener(this);
        imageGalleryAdapter.setImageThumbnailLoader(this);

        recyclerView.setAdapter(imageGalleryAdapter);
    }

    /**
     * The user selected an image, send it to the full screen image gallery activity
     * @param position the position of the image
     */
    @Override
    public void onImageClick(int position) {
        Intent intent = new Intent(ImageGalleryActivity.this, FullScreenImageGalleryActivity.class);
        Bundle bundle = new Bundle();
        bundle.putInt("position", position);
        bundle.putBoolean("editable", editable);
        intent.putExtras(bundle);
        startActivityForResult(intent, Constants.GENERAL);
    }

    /**
     * The user clicked the plus button and wants to add a new image
     * @param v the floating action button that was clicked
     */
    @Override
    public void onClick(View v) {
        if (!editable)
            return;

        if (EasyPermissions.hasPermissions(this, android.Manifest.permission.CAMERA)) {
            tempPictureFile = new IO(getApplicationContext()).getTempPictureFile();

            Uri fileUri = FileProvider.getUriForFile(getApplicationContext(), "com.cpjd.roblu", tempPictureFile);

            Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            camera.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

            startActivityForResult(camera, Constants.GENERAL);
        } else {
            Utils.showSnackbar(layout, getApplicationContext(), "Camera permission is disabled. Please enable it.",
                    true, 0);
        }
    }

    /**
     * Receives the picture that was taken by the user
     * @param requestCode the request code of the child activity
     * @param resultCode the result code of the child activity
     * @param data the picture that was taken
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == Constants.GENERAL && resultCode == FragmentActivity.RESULT_OK) {
            // fetch file from storage
            Bitmap bitmap = BitmapFactory.decodeFile(tempPictureFile.getPath());
            // fix rotation
            try {
                ExifInterface ei = new ExifInterface(tempPictureFile.getPath());
                int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_UNDEFINED);

                switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    bitmap = rotateImage(bitmap, 90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    bitmap = rotateImage(bitmap, 180);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    bitmap = rotateImage(bitmap, 270);
                    break;
                default:
                    break;
                }
            } catch (IOException e) {
                Log.d("RBS", "Failed to remove EXIF rotation data from the picture.");
            }

            /*
             * Convert the image into a byte[] and save it to the gallery
             */

            // Convert the bitmap to a byte array
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 30, stream);
            byte[] array = stream.toByteArray();

            int newID = new IO(getApplicationContext()).savePicture(eventID, array);

            // Add the image to the current array
            if (IMAGES == null)
                IMAGES = new ArrayList<>();
            IMAGES.add(array);

            // save the ID to the gallery
            for (int i = 0; i < TeamViewer.team.getTabs().get(rTabIndex).getMetrics().size(); i++) {
                if (TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i).getID() == galleryID) {
                    if (((RGallery) TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i))
                            .getPictureIDs() == null) {
                        ((RGallery) TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i))
                                .setPictureIDs(new ArrayList<Integer>());
                    }
                    ((RGallery) TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i)).getPictureIDs()
                            .add(newID);
                    break;
                }
            }
            TeamViewer.team.setLastEdit(System.currentTimeMillis());

            new IO(getApplicationContext()).saveTeam(eventID, TeamViewer.team);
            imageGalleryAdapter.notifyDataSetChanged();
        }
        /*
         * User edited an image
         */
        else if (resultCode == Constants.IMAGE_EDITED) {
            TeamViewer.team.setLastEdit(System.currentTimeMillis());

            /*
             * Update the image in the gallery
             */
            for (int i = 0; i < TeamViewer.team.getTabs().get(rTabIndex).getMetrics().size(); i++) {
                if (TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i).getID() == galleryID) {
                    if (((RGallery) TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i))
                            .getPictureIDs() == null) {
                        ((RGallery) TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i))
                                .setPictureIDs(new ArrayList<Integer>());
                    }
                    ((RGallery) TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i)).getPictureIDs()
                            .add(new IO(getApplicationContext()).savePicture(eventID,
                                    IMAGES.get(data.getIntExtra("position", 0))));
                    break;
                }
            }

            new IO(getApplicationContext()).saveTeam(eventID, TeamViewer.team);
            imageGalleryAdapter.notifyDataSetChanged();
        }
        /*
         * User deleted an image
         */
        else if (resultCode == Constants.IMAGE_DELETED) {
            // Remove the image from the gallery ID list
            for (int i = 0; i < TeamViewer.team.getTabs().get(rTabIndex).getMetrics().size(); i++) {
                if (TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i).getID() == galleryID) {
                    int pictureID = ((RGallery) TeamViewer.team.getTabs().get(rTabIndex).getMetrics().get(i))
                            .getPictureIDs().remove(data.getIntExtra("position", 0));
                    // delete from file system
                    new IO(getApplicationContext()).deletePicture(eventID, pictureID);
                    break;
                }
            }

            IMAGES.remove(data.getIntExtra("position", 0));
            imageGalleryAdapter.notifyDataSetChanged();

            TeamViewer.team.setLastEdit(System.currentTimeMillis());

            new IO(getApplicationContext()).saveTeam(eventID, TeamViewer.team);
        }
    }

    /**
     * Rotates an image
     * @param source the image to rotate
     * @param angle the angle to rotate the image by
     * @return the rotated image
     */
    private static Bitmap rotateImage(Bitmap source, float angle) {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
    }

    public void loadImageThumbnail(ImageView iv, byte[] imageUrl, int dimension) {
        imageThumbnailLoader.loadImageThumbnail(iv, imageUrl, dimension);
    }

    @Override
    public void onBackPressed() {
        finish();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setUpRecyclerView();
    }

}