It's finally easy to take photos/videos via camera or get photos/videos from gallery on Android.

Overview

Release Awesome

Shutter-Android

It's finally easy to take photos/videos via camera or get photos/videos from gallery on Android.

What is Shutter?

Shutter is an Android library to take photos, record videos, pick images/videos from gallery, with ease. I always have difficulty working with images/videos while developing Android apps especially since file providers were added.

Why use Shutter?

  • Less bugs. No more publishing apps and have your app crash on a user's devices because of file permission issues you did not handle or boilerplate code you forgot to include (believe me, I have done this many times).
  • No more copy/paste of boilerplate code. Install lib, call Shutter, and be done across all of your apps.
  • Lightweight. Check out the methods count here
  • No Android runtime permissions needed. No need to ask for reading/writing files permissions.
  • Java and Kotlin support. Shutter-Android is written in Kotlin :)

Install

Install Shutter-Android via JitPack.io.

Add the following to the root build.gradle file (/build.gradle) at the end of repositories:

allprojects {
	repositories {
	    ...
		maven { url 'https://jitpack.io' }
	}
}

Then, add the following to your project build.gradle file (app/build.gradle)

dependencies {
    compile 'com.github.levibostian:Shutter-Android:0.2.2'
}

(the latest release to date is version: Release)

Take images easily with Shutter

When you want to take a photo in your Activity or Fragment, call Shutter:

shutterResultListener = Shutter.with(this)
    .takePhoto()
    .usePrivateAppInternalStorage()
    .snap(object : Shutter.ShutterResultCallback {
        override fun onComplete(result: Shutter.ShutterResult) {
            result.absoluteImageFile // <--- file:// path to the image.
        }
        override fun onError(humanReadableErrorMessage: String, error: Throwable) {
            Log.d("SHUTTER_EXAMPLE_APP", "Error encountered: ${error.message}")
            Snackbar.make(findViewById(android.R.id.content), humanReadableErrorMessage, Snackbar.LENGTH_LONG).show()
        }
})

If you want to record a video, use: Shutter.with(this).recordVideo(). Pick image from the device gallery, use: Shutter.with(this).getPhotoFromGallery(). Pick video from the device gallery, use: Shutter.with(this).getVideoFromGallery().

When you call .snap() to tell Shutter to take a photo, save the result object. You will need to call if on your Activity or Fragment's onActivityResult() call:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (!shutterResultListener!!.onActivityResult(requestCode, resultCode, data)) {
        super.onActivityResult(requestCode, resultCode, data)
    }
}

Shutter-Android uses the FileProvider API to take photos. Because of this, Android requires you to add the following to your manifest file:

<application
   ...>
    <provider android:name="android.support.v4.content.FileProvider"
              android:authorities="${applicationId}.fileprovider"
              android:exported="false"
              android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                   android:resource="@xml/file_paths" />
    </provider>
</application>

Then, create a file: app/src/main/res/xml/file_paths.xml to specify permissions of the FileProvider API. For now, this is what the file contents should look like:

<?xml version="1.0" encoding="utf-8"?>
<paths>
</paths>

Inside of this file, add some entries depending on your situation.

  • If you are capturing an image using .usePrivateAppInternalStorage() add the following line between :
<files-path name="internal_pictures_files" path="Pictures/" />
  • If you are capturing an image using .usePrivateAppExternalStorage() add the following line between :
<external-files-path name="external_pictures_files" path="Pictures/" />
  • If you are recording a video using .usePrivateAppInternalStorage() add the following line between :
<files-path name="internal_videos_files" path="Movies/" />
  • If you are recording a video using .usePrivateAppExternalStorage() add the following line between :
<external-files-path name="external_videos_files" path="Movies/" />

Here is an example file_paths.xml file:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="internal_pictures_files" path="Pictures/" />
    <external-files-path name="external_videos_files" path="Movies/" />
</paths>

More info about how to specify permissions can be found in the official docs

Done!

Author

Levi Bostian image

Notes/Warnings:

  • The Shutter API might confuse you because you are able to save your captured media to "private internal or external storage" with the option to also "save the captured media to the gallery". This is true but not true. desi TL;DR Your photos/videos captured with Shutter may be added to the public gallery on the Android device no matter how you setup Shutter.

Android is a fragmented operating system as we all know. Even if you decide to save your photos to private internal storage and not save to the gallery, your photo still might be saved to the gallery. Shutter has no control over this. Every user device will behave differently depending on the camera app that is installed. Shutter takes photos by using an Android Intent which asks a camera app on the user's device to take the photo for us. That camera app has the ability to do with your photo whatever it wishes after it is taken including but not limited to saving the photo to the public gallery.

The only way to enforce your photos are private to your app and your app only is to add the camera functionality to your own app which we will not be covering in Shutter at this time and probably never.

"Why does shutter even give the ability to add the captured media to the public gallery if it might do it already?" you answered your own question there. Might is the keyword. Adding the ability to add the media to the gallery through Shutter is to assert it is added to the gallery even if the camera app decides not to when the photo/video is captured.

  • Create a loading UI while working with Shutter if you decide to show a photo/video after capturing it.

Shutter does labor intensive tasks in a background thread. What this means is that your app will go back into focus right away after the device camera or gallery apps are launched but the photo/video may not be ready for you yet. Shutter will call the callback you give to .snap() when the photo/video is ready. When your app goes back into focus, I would make sure to have some sort of loading UI telling the user that you are loading the photo/video and it will be available shortly. Once the callback you send to .snap() is called with the file path or an error, then you can change your UI to show the video/image and hide the loading UI.

Contribute

Shutter is open for pull requests. Please, read the STYLE.md doc in the root of this project which will answer some questions for you as to why Shutter is built the way it is.

Credits

Comments
  • Failed to find configured root

    Failed to find configured root

    I am trying to use a different line than the default <files-path name="internal_pictures_files" path="Pictures/" />

    to something like

    <files-path name="internal_pictures_files" path="images/" />

    and it causes app crash and subsequent relaunch. How should I really use to save to different directory.

    FYI: I am a novice.

    opened by gnanakeethan 5
  • When I implement Shutter-Android

    When I implement Shutter-Android

    When I implement Shutter-Android. Before even I start consuming I get this: Caused by: java.lang.RuntimeException: Manifest merger failed with multiple errors

    opened by ajkerfaisal 1
  • Add Android awesome badge to README.

    Add Android awesome badge to README.

    [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)
    

    Here is the link to where you can find the lib.

    opened by levibostian 1
  • Deprecate library for Android 11+?

    Deprecate library for Android 11+?

    opened by levibostian 0
  • Have common builder

    Have common builder

    Here is a code sample of what I am trying to do:

    var shutterBuilder = Shutter.with(this)
    
    if (useCamera) shutterBuilder = shutterBuilder.takePhoto().usePrivateAppExternalStorage()
    else shutterBuilder = shutterBuilder.getPhotoFromGallery()
    
    shutterResult = shutterBuilder
    .snap(object : ShutterResultCallback {
    

    I am trying to dynamically choose what builder I use. Depending on boolean variable useCamera.

    Problem is I cannot do this because the builder objects being returned from each are not common.

    What I could do:

    1. add a function build() that builds to a common object that you can then call snap() on.
    2. Will a kotlin DSL allow me to solve this problem from a different angle?
    opened by levibostian 0
  • Android Q scoped storage

    Android Q scoped storage

    Android Q beta has added scoped storage.

    It affects apps that store files to storage. You can store private files without needing extra permissions or you can use the devices media collections.

    https://developer.android.com/preview/privacy/scoped-storage

    opened by levibostian 1
  • Add to docs how to configure app for auto backup

    Add to docs how to configure app for auto backup

    I was reading the docs for auto backup recently and it talks about how docs in getExternalStorage() are automatically backed up.

    Add to docs how to exclude photos taken by Shutter.

    opened by levibostian 1
  • Add ability to specify the directory that photos/videos are stored after being taken.

    Add ability to specify the directory that photos/videos are stored after being taken.

    See issue https://github.com/levibostian/Shutter-Android/issues/8#issuecomment-376740206 for the discussion behind this feature.

    In the builder to take a photo or record a video, add the ability to specify the name of a directory for the photos/videos.

    Should be pretty easy. Here is the code where the directory is hard coded currently. Here is where we give the user the ability to specify the filename so we can use that same idea to give the user the ability to specify a directory.

    Tasklist:

    • [ ] Give user ability to specify the directory for taking a photo and recording a video.
    • [ ] Update readme docs showing that you can now specify a directory to save photos/videos. Also, update the readme docs about the manifest permissions where you can use "Pictures" by default, but you can also specify more for custom directories.
    opened by levibostian 0
  • Null pointer exceptions in Builders

    Null pointer exceptions in Builders

    I have been using the lib in a couple apps of mine and I have run into NPEs.

    In the builder patterns where I am doing companion.getActivity()!!, for example, could have a null activity.

    opened by levibostian 2
Releases(0.2.2)
  • 0.2.2(Jul 26, 2017)

    • Use asynctasks for running in background and UI threads for getting images/videos from gallery.
    • Fix crash where I would not return from function if user cancelled camera/gallery intent.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jul 26, 2017)

    • Allow user to get photo/video from gallery.
    • Update example app to demonstrate the ability to get photos and videos from gallery.
    • Update README to reflect the ability to get photos/videos from gallery and prepare for a more formal release.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jul 25, 2017)

    First release for Shutter-Android library.

    • Create Shutter library to be able to capture photos from camera.
    • Optionally, declare filename, where you would like to save photos to.
    • Create example app.
    • README chats about how to use library.
    Source code(tar.gz)
    Source code(zip)
Owner
Levi Bostian
Android, iOS, node API developer. Senior dev @customerio. Hacker @curiosityio . Environmental activist, minimalist, organic gardener. they/he
Levi Bostian
:iphone: [Android Library] Get device information in a super easy way.

EasyDeviceInfo Android library to get device information in a super easy way. The library is built for simplicity and approachability. It not only eli

Nishant Srivastava 1.7k Dec 22, 2022
Android gallery & photo/video functionality simplified with RxJava2

RxGallery Android gallery & photo/video functionality simplified with RxJava2 Setup To use this library your minSdkVersion must be >= 9. Add it in you

Brian Rojas 38 Oct 11, 2022
ModernStorage is a group of libraries that provide an abstraction layer over storage on Android to simplify its interactions

ModernStorage ModernStorage is a group of libraries that provide an abstraction layer over storage on Android to simplify its interactions by apps dev

Google 1.1k Dec 30, 2022
PhotoSync - app to backup photos to your own computer

PeopleInSpace Minimal Kotlin Multiplatform project with SwiftUI, Jetpack Compose

Kyle McBurnett 0 Jan 2, 2022
SPIDlibraryAndroid is a library for logging in via SPID through several different identity providers.

SPIDlibraryAndroid SPIDlibraryAndroid is a library for logging in via SPID through several different identity providers.

INPS 98 Dec 15, 2022
Migrating from one PostgreSQL to another via S3

Migrating from one PostgreSQL to another via S3 In one terminal start initial setup. ./gradlew buildDockerImage docker-compose up --build dbmig-s3 dbm

Stefan Bissell 1 May 19, 2022
LearningRegex - Parse links from text via RegEx

Parse links from text via RegEx Supported types: Hashtags Urls emails Using in p

Boris 0 Feb 16, 2022
Get a unique ID for Android devices without any permissions.

Java and Kotlin Android library. Uniquely identify an Android device without any permissions and API restrictions. The recommended approach using DRM API.

Eyosiyas Bereketab 9 Aug 25, 2022
Android library which makes it easy to handle the different obstacles while calling an API (Web Service) in Android App.

API Calling Flow API Calling Flow is a Android library which can help you to simplify handling different conditions while calling an API (Web Service)

Rohit Surwase 19 Nov 9, 2021
[] Easy async loading for Android's ListView/GridView

NOTE: Smoothie's API is not final yet. Although the library is fairly funcional, this is still beta-quality code. Do not rely on it for production cod

Lucas Rocha 988 Dec 22, 2022
Very easy to use wrapper library for Android SharePreferences

Treasure English document Treasure是一个Android平台上基于SharePreferences的偏好存储库,只需要定义接口,无需编写实现,默认支持Serializable和Parcelable。运行时0反射,不仅使用方便而且性能和原生写法几乎无差别。 使用方法 1

星一 507 Nov 12, 2022
Access and process various types of personal data in Android with a set of easy, uniform, and privacy-friendly APIs.

PrivacyStreams PrivacyStreams is an Android library for easy and privacy-friendly personal data access and processing. It offers a functional programm

null 269 Dec 1, 2022
Easy SharedPreference Engine foR ANDROid

esperandro Easy SharedPreference Engine foR ANDROid What? esperandro makes it simple to use SharedPreferences in a nicer and less error-prone way. Wit

David Kunzler 184 Nov 25, 2022
A simple and easy to use stopwatch and timer library for android

TimeIt Now with Timer support! A simple and easy to use stopwatch and timer library for android Introduction A stopwatch can be a very important widge

Yashovardhan Dhanania 35 Dec 10, 2022
An easy-to-use, cross-platform measurement tool that pulls data out of CD pipelines and analysis the four key metrics for you.

Maintained by SEA team, ThoughtWorks Inc. Read this in other languages: English, 简体中文 Table of Contents About the Project Usage How to Compute Contrib

Thoughtworks 277 Jan 7, 2023
Compose easy forms validation library

Compose EasyForms Focus on building your form UI while the library do the heavy work for you. Features Built in support for most of the Form widgets i

Kosh Sergani 24 Jul 18, 2022
Interactive prompts made easy!

Interactive prompts made easy!

David Simon 1 Nov 1, 2021
This is a easy way to publish MQTT message and receive MQTT message

SMQ-CLIENT This is a easy way to publish MQTT message and receive MQTT message This is provider a spring stater for quick use Recive message form the

SUDA 1 Apr 25, 2022
Android Shared preference wrapper than encrypts the values of Shared Preferences. It's not bullet proof security but rather a quick win for incrementally making your android app more secure.

Secure-preferences - Deprecated Please use EncryptedSharedPreferences from androidx.security in preferenced to secure-preference. (There are no active

Scott Alexander-Bown 1.5k Dec 24, 2022