Android Camera and ImagePicker

0
User Management System
Learn Kotlin, Retrofit, MVVM and MySQL using this all-in-one app. It is designed to be beginner friendly.

In this article we want to look at several third party options to obtain an image from the camera. This may in form of directly capturing the image, or selecting the image from gallery or filesystem.

(a). Gligar

Gligar is as easy as it gets.

  • Gligar
  • Example

OpenSooq logo

Gliger [Android Image Picker Library]

API

API License
Download
Android Arsenal

:star: Star us on GitHub — it helps!

forthebadge

Gliger is an Easy, lightweight and high performance image picker library for Android!
Gliger load images using Android content resolver with the help of coroutines to lazy load the images and improve the performance!
Gliger handle permission requests, support camera capture, and limit for the max number of images to pick.

Demo

Table of content

Download

This library is available in jCenter which is the default Maven repository used in Android Studio. You can also import this library from source as a module.

dependencies {
    // other dependencies here
    implementation 'com.opensooq.supernova:gligar:1.1.0'
}

Sample Project

We have a sample project demonstrating how to use the library.

Checkout the demo here

Usage

Simpler than ever!

To open the Picker:

Kotlin

GligarPicker().requestCode(PICKER_REQUEST_CODE).withActivity(this).show()

Java

new GligarPicker().requestCode(PICKER_REQUEST_CODE).withActivity(this).show();

To get the result override onActivityResult method:

Kotlin

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK) {
            return
        }

        when (requestCode) {
            PICKER_REQUEST_CODE -> {
                val imagesList = data?.extras?.getStringArray(GligarPicker.IMAGES_RESULT)// return list of selected images paths.
                if (!imagesList.isNullOrEmpty()) {
                    imagesCount.text = "Number of selected Images: ${imagesList.size}"
                }
            }
        }
    }

Java

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        switch (requestCode){
            case PICKER_REQUEST_CODE : {
              String pathsList[]= data.getExtras().getStringArray(GligarPicker.IMAGES_RESULT); // return list of selected images paths.
                imagesCount.text = "Number of selected Images: " + pathsList.length;
                break;
            }   
        }
    }
Method usage
withActivity(activity: Activity) used to set the activity will recive the result
withFragment(fragment: Fragment) used to set the fragment will recive the result
requestCode(requestCode: Int) used to set the request code for the result
limit(limit: Int) used to set the max number of images to select
disableCamera(disableCamera: Boolean) by default the value of disableCamera is false, it determine to allow camera captures or not
cameraDirect(cameraDirect: Boolean) by default the value of cameraDirect is false, it determine to open the camera before showing the picker or not

UI customization

Customizable Colors

override any color to change inside your project colors.xml

Property Description
counter_bg selection counter background color
counter_color selection counter text color
selector_color selection tint color
place_holder_color empty image holder color
ripple_color selection ripple color
toolbar_bg toolbar color
done Done button color
change_album_color change album text color
camera_icon_color camera icon color
camera_text_color camera text color
permission_alert_bg permission alert background color
permission_alert_color permission alert text color

Customizable Texts

override any string to change inside your project strings.xml

Property Description
over_limit_msg selection limit reached message
capture_new_image capture image text
change_album_text change album text
permission_storage_never_ask permission denied message
all_images all images album name

License


Copyright 2019 OpenSooq

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
📸Image Picker for Android, Pick an image from Gallery or Capture a new image with Camera.
No. Key Value
1. Created 2019-12-01T08:42:45Z
2. Updated 2021-04-05T19:31:15Z
3. Stars 99
5. Forks 17
6. Language Kotlin
7. Lib Author OpenSooq

This Library was written By: OpenSooq

MainActivity.java


import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.opensooq.supernova.gligar.GligarPicker
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    val PICKER_REQUEST_CODE = 30

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        GligarPicker().limit(10).disableCamera(false).cameraDirect(false).requestCode(PICKER_REQUEST_CODE)
            .withActivity(this).show()
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK) {
            return
        }

        when (requestCode) {
            PICKER_REQUEST_CODE -> {
                val imagesList = data?.extras?.getStringArray(GligarPicker.IMAGES_RESULT)
                if (!imagesList.isNullOrEmpty()) {
                    imagesCount.text = "Number of selected Images: ${imagesList.size}"
                }
            }
        }
    }

}

  • Product
  • Specification
  • Photos
This is a Family Gallery App project ready for Play store. This app will help you master the following technologies
  • Kotlin Full Android app ...
  • Added to wishlistRemoved from wishlist 0
    Add to compare
    Programming Language

    Kotlin

    Design Pattern

    Model View ViewModel

    Text Database

    Firebase Realtime Database

    Image Database

    Firebase Cloud Storage

    Authentication

    Firebase Authentication

    Runtime Permissions

    Dexter

    Image Slider

    CarouselView

    Listings View

    Image Gallery

     

    (b). EasyImage

    • EasyImage
    • Example

    Android Arsenal

    What is it?

    EasyImage allows you to easily capture images and videos from the gallery, camera or documents without creating lots of boilerplate.

    Setup

    Runtime permissions

    This library requires specific runtime permissions. Declare it in your AndroidManifest.xml:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

    Please note: for devices running API 23 (marshmallow) you have to request this permissions in the runtime, before calling EasyImage.openCamera(). It's demonstrated in the sample app.

    There is also one issue about runtime permissions. According to the docs:

    If your app targets M and above and declares as using the CAMERA permission which is not granted, then attempting to use this action will result in a SecurityException.

    For this reason, if your app uses CAMERA permission, you should check it along with WRITE_EXTERNAL_STORAGE before calling EasyImage.openCamera()

    Gradle dependency

    Get the latest version from jitpack

    Usage

    Essentials

    Create your EasyImageInstance like this:

    EasyImage easyImage = new EasyImage.Builder(context)
    
    // Chooser only
    // Will appear as a system chooser title, DEFAULT empty string
    //.setChooserTitle("Pick media")
    // Will tell chooser that it should show documents or gallery apps
    //.setChooserType(ChooserType.CAMERA_AND_DOCUMENTS)  you can use this or the one below
    //.setChooserType(ChooserType.CAMERA_AND_GALLERY)
    // saving EasyImage state (as for now: last camera file link)
    .setMemento(memento)
    
    // Setting to true will cause taken pictures to show up in the device gallery, DEFAULT false
    .setCopyImagesToPublicGalleryFolder(false)
    // Sets the name for images stored if setCopyImagesToPublicGalleryFolder = true
    .setFolderName("EasyImage sample")
    
    // Allow multiple picking
    .allowMultiple(true)
    .build();

    Taking image straight from camera

    • easyImage.openCameraForImage(Activity activity,);
    • easyImage.openCameraForImage(Fragment fragment);

    Capturing video

    • easyImage.openCameraForVideo(Activity activity);
    • easyImage.openCameraForVideo(Fragment fragment);

    Taking image from gallery or the gallery picker if there is more than 1 gallery app

    • easyImage.openGallery(Activity activity);
    • easyImage.openGallery(Fragment fragment);

    Taking image from documents

    • easyImage.openDocuments(Activity activity);
    • easyImage.openDocuments(Fragment fragment);

    Displaying system picker to chose from camera, documents, or gallery if no documents apps are available

    • easyImage.openChooser(Activity activity);
    • easyImage.openChooser(Fragment fragment);

    Getting the photo file

        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            easyImage.handleActivityResult(requestCode, resultCode, data, this, new DefaultCallback() {
                @Override
                public void onMediaFilesPicked(MediaFile[] imageFiles, MediaSource source) {
                    onPhotosReturned(imageFiles);
                }
    
                @Override
                public void onImagePickerError(@NonNull Throwable error, @NonNull MediaSource source) {
                    //Some error handling
                    error.printStackTrace();
                }
    
                @Override
                public void onCanceled(@NonNull MediaSource source) {
                    //Not necessary to remove any files manually anymore
                }
            });
        }

    Known issues

    Library was pretty much rewritten from scratch in kotlin on 29.03.2019. Initial version 3.0.0 might be unstable. In case of problems fallback to version 2.1.1 Also version 3.0.0 is not backward compatible and will require some changes of those who used previous versions. These are not big tho. Updated readme explains it all.

    License

    Copyright 2015 Jacek Kwiecień.
    
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
       http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    Library for picking pictures from gallery or camera
    No. Key Value
    1. Created 2015-11-03T14:51:26Z
    2. Updated 2021-04-05T03:50:31Z
    3. Stars 1562
    5. Forks 289
    6. Language Kotlin
    7. Lib Author jkwiecien

    This Library was written By: jkwiecien

    MainActivity.java

    
    import android.Manifest;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    
    import androidx.annotation.NonNull;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.app.ActivityCompat;
    import androidx.core.content.ContextCompat;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    import pl.aprilapps.easyphotopicker.ChooserType;
    import pl.aprilapps.easyphotopicker.DefaultCallback;
    import pl.aprilapps.easyphotopicker.EasyImage;
    import pl.aprilapps.easyphotopicker.MediaFile;
    import pl.aprilapps.easyphotopicker.MediaSource;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String PHOTOS_KEY = "easy_image_photos_list";
        private static final int CHOOSER_PERMISSIONS_REQUEST_CODE = 7459;
        private static final int CAMERA_REQUEST_CODE = 7500;
        private static final int CAMERA_VIDEO_REQUEST_CODE = 7501;
        private static final int GALLERY_REQUEST_CODE = 7502;
        private static final int DOCUMENTS_REQUEST_CODE = 7503;
    
        protected RecyclerView recyclerView;
    
        protected View galleryButton;
    
        private ImagesAdapter imagesAdapter;
    
        private ArrayList photos = new ArrayList<>();
    
        private EasyImage easyImage;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            recyclerView = findViewById(R.id.recycler_view);
            galleryButton = findViewById(R.id.gallery_button);
    
            if (savedInstanceState != null) {
                photos = savedInstanceState.getParcelableArrayList(PHOTOS_KEY);
            }
    
            imagesAdapter = new ImagesAdapter(this, photos);
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.setHasFixedSize(true);
            recyclerView.setAdapter(imagesAdapter);
    
            easyImage = new EasyImage.Builder(this)
                    .setChooserTitle("Pick media")
                    .setCopyImagesToPublicGalleryFolder(false)
    //                .setChooserType(ChooserType.CAMERA_AND_DOCUMENTS)
                    .setChooserType(ChooserType.CAMERA_AND_GALLERY)
                    .setFolderName("EasyImage sample")
                    .allowMultiple(true)
                    .build();
    
            checkGalleryAppAvailability();
    
    
            findViewById(R.id.gallery_button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    /** Some devices such as Samsungs which have their own gallery app require write permission. Testing is advised! */
                    String[] necessaryPermissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
                    if (arePermissionsGranted(necessaryPermissions)) {
                        easyImage.openGallery(MainActivity.this);
                    } else {
                        requestPermissionsCompat(necessaryPermissions, GALLERY_REQUEST_CODE);
                    }
                }
            });
    
    
            findViewById(R.id.camera_button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String[] necessaryPermissions = new String[]{Manifest.permission.CAMERA};
                    if (arePermissionsGranted(necessaryPermissions)) {
                        easyImage.openCameraForImage(MainActivity.this);
                    } else {
                        requestPermissionsCompat(necessaryPermissions, CAMERA_REQUEST_CODE);
                    }
                }
            });
    
            findViewById(R.id.camera_video_button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String[] necessaryPermissions = new String[]{Manifest.permission.CAMERA};
                    if (arePermissionsGranted(necessaryPermissions)) {
                        easyImage.openCameraForVideo(MainActivity.this);
                    } else {
                        requestPermissionsCompat(necessaryPermissions, CAMERA_VIDEO_REQUEST_CODE);
                    }
                }
            });
    
            findViewById(R.id.documents_button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    /** Some devices such as Samsungs which have their own gallery app require write permission. Testing is advised! */
                    String[] necessaryPermissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
                    if (arePermissionsGranted(necessaryPermissions)) {
                        easyImage.openDocuments(MainActivity.this);
                    } else {
                        requestPermissionsCompat(necessaryPermissions, DOCUMENTS_REQUEST_CODE);
                    }
                }
            });
    
            findViewById(R.id.chooser_button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String[] necessaryPermissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
                    if (arePermissionsGranted(necessaryPermissions)) {
                        easyImage.openChooser(MainActivity.this);
                    } else {
                        requestPermissionsCompat(necessaryPermissions, CHOOSER_PERMISSIONS_REQUEST_CODE);
                    }
                }
            });
    
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putSerializable(PHOTOS_KEY, photos);
        }
    
        private void checkGalleryAppAvailability() {
            if (!easyImage.canDeviceHandleGallery()) {
                //Device has no app that handles gallery intent
                galleryButton.setVisibility(View.GONE);
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
            if (requestCode == CHOOSER_PERMISSIONS_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                easyImage.openChooser(MainActivity.this);
            } else if (requestCode == CAMERA_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                easyImage.openCameraForImage(MainActivity.this);
            } else if (requestCode == CAMERA_VIDEO_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                easyImage.openCameraForVideo(MainActivity.this);
            } else if (requestCode == GALLERY_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                easyImage.openGallery(MainActivity.this);
            } else if (requestCode == DOCUMENTS_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                easyImage.openDocuments(MainActivity.this);
            }
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            easyImage.handleActivityResult(requestCode, resultCode, data, this, new DefaultCallback() {
                @Override
                public void onMediaFilesPicked(MediaFile[] imageFiles, MediaSource source) {
                    for (MediaFile imageFile : imageFiles) {
                        Log.d("EasyImage", "Image file returned: " + imageFile.getFile().toString());
                    }
                    onPhotosReturned(imageFiles);
                }
    
                @Override
                public void onImagePickerError(@NonNull Throwable error, @NonNull MediaSource source) {
                    //Some error handling
                    error.printStackTrace();
                }
    
                @Override
                public void onCanceled(@NonNull MediaSource source) {
                    //Not necessary to remove any files manually anymore
                }
            });
        }
    
        private void onPhotosReturned(@NonNull MediaFile[] returnedPhotos) {
            photos.addAll(Arrays.asList(returnedPhotos));
            imagesAdapter.notifyDataSetChanged();
            recyclerView.scrollToPosition(photos.size() - 1);
        }
    
        private boolean arePermissionsGranted(String[] permissions) {
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
                    return false;
    
            }
            return true;
        }
    
        private void requestPermissionsCompat(String[] permissions, int requestCode) {
            ActivityCompat.requestPermissions(MainActivity.this, permissions, requestCode);
        }
    }
    

    Android MySQL Retrofit2 Multipart CRUD,Search,Pagination rating

    When I was a 2nd year Software Engineering student, I buillt a now defunct online tool called Camposha(from Campus Share) using my then favorite language C#(ASP.NET) to compete OLX in my country(Kenya). The idea was to target campus students in Kenya. I got a few hundred signups but competing OLX proved too daunting. I decided to focus on my studies, learning other languages like Java,Python,Kotlin etc while meanwhile publishing tutorials at my YouTube Channel ProgrammingWizards TV which led to this site(camposha.info). Say hello or post me a suggestion: oclemmi@gmail.com . Follow me below; Github , and on my channel: ProgrammingWizards TV

    We will be happy to hear your thoughts

    Leave a reply

    77 − seventy six =

    Reset Password
    Compare items
    • Total (0)
    Compare
    0
    Shopping cart