The Missing Documentation: Camera Intents
Whenever I follow Google’s documentation, it seems like it only gets me 90% to the solution. There always seems to be something minor that causes major problems. I was learning to Take Photos Simply and faced that exact problem.
I will just break down what you need to do step by step, so you don’t have go hunting through StackOverflow or Github Gists.
1. Create Image File
First we need to create a File
that the Camera will save the image to:
- Make sure to give your image a unique file name. I am using
System.currentTimeMillis()
to ensure that. - Notice the commented out code on Line 6&7. Use that if you want to add it to the image gallery so that other apps can access the photo taken using your app. Beginning in Android 6.0 (API level 23), you will need to ask for permissions during run time, so don’t forget to do that. You can use a library like Permiso to help you out with that.
2. Declare Permissions
Since we are saving it our app’s private directory (Line 5 above), we need to ask for WRITE_EXTERNAL_STORAGE
permission for Android 4.3 and lower. Starting from Android 4.4 (SDK 19), Google decided that it was no longer required because the directory is private to your app. However, I ran into an issue where the Nexus 7 was still asking for permission even though it was running Android 5.1 (SKD 22). Google will tell you the maxSdkVersion
needs to only be 18, but I had to bump it up to 22.
- Note: By asking for
WRITE_EXTERNAL_STORAGE
permission, we will automatically be gettingREAD_EXTERNAL_STORAGE
permission. - Also notice the commented out section. If you decide to save it to the image gallery, all versions of the app needs the
WRITE_EXTERNAL_STORAGE
permission. - Can someone enlighten me to why I had to bump it up to
maxSdkVersion=22
? It seems to be a common problem: http://stackoverflow.com/questions/31831453
I ended up using this solution like I said above:
http://stackoverflow.com/questions/31831453/getexternalfilesdir-fail
3. Configure the FileProvider
We need to add a FileProvider
to AndroidManifest.xml
so that the camera can write to the file we provide.
file_paths.xml
goes into thexml
folder in theres
folder of your app (i.e. res/xml/file_paths.xml)- Note that if you decide different than
getExternalFilesDir(Environment.DIRECTORY_PICTURES)
, you need to check out the documentation ofFileProvider
to see what you should use instead ofexternal-path
- Also note that what we use in
android:authorities
will later be used when we create theURI
(see below: Line 15)
4. Create & Start the Intent
When we create the Intent
, we need check to make sure that the device has a camera and is able to accept the Intent
. In addition we need to add flags to grant the camera permissions to write into the file we provide.
- Note that this
String
:BuildConfig.APPLICATION_ID + “.fileprovider”
needs to match what we setandroid:authorities
to inAndroidManifest.xml
above.