I am following Google's Taking Photos Simply tutorial, but it is failing on the temp file creation with an java.io.IOException: open failed: EACCES (Permission denied).
Here is my AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pricez.fastshop_android" >
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
<uses-feature android:required="true" android:name="android.hardware.camera"/>
<!-- Rest of file... -->
</manifest>
So, I guess that at least this is correct.
Here is the relevant code of my activity:
private String mCurrentPhotoPath;
private static final int REQUEST_TAKE_PHOTO = 1;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "/JPEG_" + timeStamp + "_"; // I forgot from where I got this, but it was from some SO question that tried to deal with a similar problem
File absoluteFileDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsoluteFile(); // Same as above
Log.i("createImageFile", "absoluteFileDir.getAbsolutePath(): " + absoluteFileDir.getAbsolutePath()); // I/createImageFile﹕ absoluteFileDir.getAbsolutePath(): /storage/sdcard/Android/data/-redacted-/files/Pictures
File image = File.createTempFile(imageFileName, ".jpg", absoluteFileDir);
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
public void takePhoto(View view) {
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Toast.makeText(this, "External SD card not mounted", Toast.LENGTH_LONG).show();
return;
}
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile;
try {
photoFile = createImageFile();
} catch (IOException e) {
Log.e("takePhoto", "IOException", e);
return;
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
// Get the dimensions of the View
ImageView imgv = (ImageView)findViewById(R.id.imgPreview);
int targetW = imgv.getWidth();
int targetH = imgv.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
//
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
imgv.setImageBitmap(bitmap);
}
}
EDIT 1:
I'm running this on a emulator, with SDK level 19.
EDIT 2:
If I delete the folders by hand, the getExternalStorageDirectory starts working fine. I'm leaving this question open because it's not really a fix. If everything keeps working in my code, I'm going to close in a few days.
I have no idea why (my guess is that something in the file locks has silently gone horribly wrong), but it started working when I deleted and recreated the folder (Kudos to #greenapps, would upvote if I could). What I can do at this point is to think how to recover somehow.
I don't think deleting the folder is the actual solution, but I have to move on at this point.
Plus, the situation might not present itself in an actual device.
Related
I'm new in Android and I've follow this tutorial https://developer.android.com/training/camera/photobasics.html and I can't create folder in /storage/emulated/0/Pictures.
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getPublicAlbumStorageDir("FileName");
if (storageDir ==null){
Toast.makeText(this, "Sorry no folder available", Toast.LENGTH_LONG).show();
return storageDir;
}
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
Someone told me to use getPublicAlbumStorageDir() https://developer.android.com/training/data-storage/files.html#java instead of getExternalFilesDir(Environment.DIRECTORY_PICTURES)
public File getPublicAlbumStorageDir(String albumName) throws IOException {
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), albumName);
Log.i("File", file.getAbsolutePath());
if (!file.exists()) {
Log.e("Error", file.getAbsolutePath());
file.mkdirs();
if(!file.exists()){
Log.e("Error22", file.getAbsolutePath());
}
else{
Log.i("In", "you are in");
return file;
}
return null;
}
return file;
}
Here are my permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I've try to found more about this issue and the only working project is on this site, but some of the actions are old.
I'm using for testing Android 8.0.0 and also Android 6.0.0.
It's working
If you want to make a folder on gallery, this how you should do:
Go to https://developer.android.com/training/camera/photobasics.html#TaskPath and copy permissions to your AndroidManifest.xml as adding a FileProvider inside <application> tags. Then inside res or resource, create a folder with the name xml and inside make a xml file called file_paths, in the file copy what is under FileProvider but change path to path=".".
(Don´t forget to ask permissions to the user, if you use it for real).
In the same page, above you will find private void dispatchTakePictureIntent(), copy that and static final int REQUEST_TAKE_PHOTO = 1. dispatchTakePictureIntent() is the first thing you need to call, in order to work.
After that, create a String mCurrentPath and copy Private File createImageFile() from above.
Next, copy public File getPublicAlbumStorageDir(String albumName) which is above this explanation.
If you run it it will show the camera and you can deny or accept the photo you take. However you still have to add a little more code.
String REQUEST_TAKE_PHOTO = 2;
#Override
protected void onActivity(int requestCode, int requestCode, Intent data){
if(requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK){
//Show ImageView here if you want
galleryAddPic();
}
super.onActivityResult(requestCode, resultCode, data);
}
In https://developer.android.com/training/camera/photobasics.html#TaskGallery duplicate private void galleryAddPic() and if you want to show the image taken, add this:
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath());
imageView.setImageBitmap(bitmap);
And like so, your image should be in the FolderName you have defined.
I decided to make this small tutorial because I couldn't find the answer for this problem and in Android website is not well explain.
Huge thanks to greenapps! I really appreciate!
I'm trying to save an image on JPG format on a specific folder from my gallery. But my code is not creating a directory, whenever i create a Toast it return for me /storage/emulated/0/DCIM/MyFodler,but when will i open the gallery, this foder not exist. I'm building the application direct of my devide with Android Marshmallow 6.0.
Code to create Bitmap:
private Bitmap getToBitmap(ImageView view, int Width, int Heigth){
Bitmap bitmap = Bitmap.createBitmap(Width,Heigth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
Code to try save the image on gallery:
private void TrySaveMediaStore(){
String path = Environment.getExternalStorageDirectory().toString();
OutputStream FileOut = null;
File file = new File(path,"DCIM/MyFolder");
file.mkdirs();
Toast.makeText(getApplicationContext(),file.getAbsolutePath(),Toast.LENGTH_SHORT).show();
try{
FileOut = new FileOutputStream(file);
FileOut.flush();
FileOut.close();
Bitmap bitmap = getToBitmap(img,img.getMaxWidth(),img.getMaxHeight());
bitmap.compress(Bitmap.CompressFormat.JPEG,100,FileOut);
MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
Toast.makeText(this,file.getAbsolutePath(),Toast.LENGTH_SHORT).show();
}catch (FileNotFoundException e){
return;
}catch (IOException e){
e.printStackTrace();
}
}
Androidmanifest permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
DCIM/MyFolder is a directory. You create this as a directory using mkdirs().
You cannot then try using DCIM/MyFolder as a filename for saving a JPEG. You need to create a file inside the directory.
So, instead of:
FileOut = new FileOutputStream(file);
use something like:
File theActualImageFile=new File(file, "something.jpeg");
FileOut = new FileOutputStream(theActualImageFile);
Also:
You need to deal with runtime permissions, if your targetSdkVersion is 23 or higher
A gallery app will see neither the directory nor the file, until you tell the MediaStore to index the newly-created JPEG
i think a had the same problem, actually the image do insert just fine in the memory, but when i tried to watch it didn't show as i expected, i solved it refreshing the gallery with the scanner class, used this code:
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
See this link for more info: How can I refresh the Gallery after I inserted an Image in android?
You may use the below code for asking runtime storage permission:
final int MyVersion = Build.VERSION.SDK_INT;
if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
if (!checkIfAlreadyhavePermission()) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
} else {
TrySaveMediaStore() ;
}
checkIfAlreadyhavePermission() method:
private boolean checkIfAlreadyhavePermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED;
}
Add onRequestPermission():
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
TrySaveMediaStore();
} else {
Toast.makeText(this, "Please give your permission.", Toast.LENGTH_LONG).show();
}
break;
}
}
}
After creating the file scan MediaStore:
public void scanFile(Context c, File file, String mimeType) {
MediaScannerConnection
.scanFile(c, new String[] {file.getAbsolutePath()},
new String[] {mimeType}, null);
}
Yes, the problem is the media scanner. Yo can simply check the file using a terminal (download the app if you don't have it) and go manually to the directory. I had the same problem, but at least I know the file is there.
I have this weird problem that seems to only happen on one of my tablets that runs android 6.
I have this chunk of code to add a photo taken from the camera to a recycler view
1) I create a file object onto device (this is the photo)
2) I get the uri from that file
3) I create an intent passing in that uri as such
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null)
// this is done in a fragment, everything else below is in the if statement
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(take_photo_intent, option_int);
I know MediaStore.EXTRA_OUTPUT does NOT return anything to onActivityResult, but instead writes to the uri you pass in.
now inside of onActivityResult I have
Log.i("PHOTO", "path--->" + uri.getPath());
So I want to mention, when the program works or DOESN'T work, the uri ALWAYS has a path, one example of one of the paths is
/storage/emulated/0/data/20161212_175150797715155.jpg
so to continue on in the onActivityResult
5) create bitmap based on uri path to use it later on
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
*************** problem here ****************
Bitmap temp = BitmapFactory.decodeFile(uri.getPath());
the temp bitmap returns null SOME of the time, let me explain
when I take the photo, the asus android 6 tablet shows two buttons when you take the photo, one button to discard the photo, another to keep the photo.. here is the weird part, ON THAT screen, if I wait like 5-15 seconds before pressing the button to keep the photo, the bitmap will NOT be null, but if I take a photo and immediately accept it, the a bitmap is null.
now as said before, does not matter how i do it, if the bitmap comes out null, or it does not come out null, it always has a path before passing it into the bitmapdecode function (which is weird)
I have no clue if it is the camera software, the physical camera hardware, an android 6 bug....
I also want to say, I am not sure if this is the best code but it has worked on 4 other android devices ( phones, tablets) it is just this ONE tablet that is a asus and only one with android 6, it works fine with everything else
EDIT:
I tried this as suggested
Bitmap TEMP = null;
try {
TEMP = BitmapFactory.decodeStream(getContext().getContentResolver().openInputStream(uri));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
with no luck
EDIT 2:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap TEMP = BitmapFactory.decodeFile(uri.getPath());
Bitmap bitmap_image = ThumbnailUtils.extractThumbnail(TEMP, THUMBNAIL_SIZE, THUMBNAIL_SIZE);
if (bitmap_image == null)
Log.i("PHOTO", "BITMAP THUMBNAIL NULL");
setAdapterBitmap(bitmap_image, uri.getPath(), 1);
}
}
SOLUTION:
I had this method to create a File object and turn it into a URI Object
private File createFileForImage() throws IOException {
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = DIR_NAME + "_" + file_creation_time;
File storage_dir = new File(String.valueOf(Environment.getExternalStorageDirectory()), DIR_NAME);
if (!storage_dir.exists())
{
if(!storage_dir.mkdir())
{
return null;
}
}
return File.createTempFile(image_file_name, ".jpg", storage_dir);
}
then I used this after it was return
uri = Uri.fromFile(image_file);
but for some reason this was working but it had a slight delay that cause bizarre behavior as stated in the original post
Jan Kaufmann suggestion seem to work, to i made some small modifications
private Uri getOutputMediaUriFromFile()
{
File photo_storage_dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), DIR_NAME);
if (!photo_storage_dir.exists())
{
if (!photo_storage_dir.mkdirs())
{
return null;
}
}
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = "ipr" + "_" + file_creation_time;
File photo = new File(photo_storage_dir.getPath() + File.separator + image_file_name + ".jpg");
return Uri.fromFile(photo);
}
It does essentially the same thing, but for some reason this doesn't cause the issue I was having, at least not with my testing.
I am glad this now works but can anyone explain why this worked?
Make sure the image size is not too big. If needed,subsample the original image to save memory
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inSampleSize = 8;
Make sure you have permission for
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Or try constructing your URI into something like this:
Uri uri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE, "myimage"); where getOutputMediaFileUri is :
private File getOutputMediaFile(int type, String imgname) {
// External sdcard location
//public static String DIRECTORY_PICTURES = "Pictures";
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + imgname + ".jpg");
} else {
return null;
}
return mediaFile;
}
Try this dude:
TEMP = MediaStore.Images.Media.getBitmap(context.getContentResolver(), YOUR_URL);
If this is not work, I guess that you didn't create a temp file to save the image.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try{
GEY_FILE;
}catch (Exception ex){
Log.i(TAG, "run: " + ex);
}
}
}, 15000);
I'm making a simple notebook app, in which a note can have an image attached to it. I can take a photo just fine, and after the photo has been taken, it is correctly displayed in an imageview inside the note. After the note has been saved, the path to the photo is saved in a database. The path is correctly saved. Next, when the user opens the note, the path is correctly found in the database -- however, I am not able to load it into the imageview. Rather, the imageview turns white. As I manually take a look into the folder where the image is supposed to be saved, I see that the image isn't being saved to the phone or SD card at all, and I have no idea how to save it. I've been looking all over the internet and StackOverflow, but haven't found a solution.
public void onIcTakePhotoClick(View icon) {
File imageFile = null;
Intent takePictureIntent;
try {
imageFile = ImageHelper.createImageFile(this);
} catch (IOException e) {
e.printStackTrace();
}
if (imageFile != null) {
mImagePath = imageFile.getAbsolutePath();
//mImagePath = ImageHelper.getImagePath(imageFile);
takePictureIntent = ImageHelper.dispatchTakePictureIntent(this, imageFile);
startActivityForResult(takePictureIntent, ImageHelper.REQUEST_IMAGE_CAPTURE);
} else {
// error message
}
}
All of the above (creating a file, a path, and an intent) work well:
public static File createImageFile(Context context) throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return image;
}
public static Intent dispatchTakePictureIntent(Context context, File photoFile) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
// Continue only if the File was successfully created
Uri photoURI = FileProvider.getUriForFile(context,
"com.bergdahl.notebook.fileprovider",
photoFile);
//takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
return takePictureIntent;
}
return null;
}
The filepath ends up looking like this: "/storage/emulated/0/Android/data/com.myname.notebook/files/Pictures/JPEG_20160824_213643_135920553.jpg". Next I get the result:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ImageHelper.REQUEST_IMAGE_CAPTURE: {
if (resultCode == RESULT_OK) {
ImageHelper.handleCameraPhoto(this, imageView, mImagePath);
}
break;
}
}
}
In which I use methods created by the Android team (https://developer.android.com/training/camera/photobasics.html):
public static void handleCameraPhoto(Activity context, ImageView imageView, String imagePath) {
if (imagePath != null) {
ImageHelper.setPic(imagePath, imageView);
ImageHelper.galleryAddPic(context, imagePath);
}
}
public static void setPic(String imagePath, ImageView imageView) {
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the ImageView */
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW/targetW, photoH/targetH);
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
/* Associate the Bitmap to the ImageView */
imageView.setImageBitmap(bitmap);
imageView.setVisibility(View.VISIBLE);
}
public static void galleryAddPic(Activity context, String imagePath) {
Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
File f = new File(imagePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
}
And finally, the code for opening up the note later:
if (mNote.getFilePath() != null) {
mImagePath = mNote.getFilePath();
//ImageHelper.handleCameraPhoto(this, imageView, mNote.getFilePath());
//File file = new File(mImagePath);
//imageView.setImageDrawable(Drawable.createFromPath(mImagePath));
//Uri uri = Uri.parse("file:" + mNote.getFilePath());
//imageView.setImageURI(uri);
}
In the manifest, I've specified the permission for writing to external storage. So, to reiterate, I need help figuring out how to save the image that I've taken onto the device, so that I can later load it into an imageview next time the user opens the note. Thank you in advance for the help!
EDIT: I tried the image.createNewFile()-method, but the outcome is sadly the same. The boolean test is true.
public static File createImageFile(Context context) throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
/*
File image = File.createTempFile(
imageFileName,
".jpg",
storageDir
);
*/
File image = new File(storageDir, imageFileName + ".jpg");
if (!image.exists()) {
try {
boolean test = image.createNewFile();
Log.d("createImageFile", test + "");
} catch (IOException e) {
e.printStackTrace();
}
}
return image;
}
EDIT again: The image now correctly shows up on an emulator, but it doesn't work on my actual device. The emulator runs 6.0, my device 6.0.1. My device has granted permissions and has external storage. I've been trying to change the directory, but to no success.
Try to replace
mImagePath = imageFile.getAbsolutePath();
with
mImagePath = "file:" + imageFile.getAbsolutePath();
With Android 6 you won't have the read/write permission after installing even if you have declared it in your manifest. You have to ask for it first at runtime:
https://developer.android.com/training/permissions/requesting.html
For testing purposes you can give your app the permissions in the app settings menu without implementing the query.
add the Permission runtime..
if (Build.VERSION.SDK_INT >= 23)
{
if (checkPermission())
{
// Code for above or equal 23 API Oriented Device
// Create a common Method for both
///take camera caputure code
} else {
requestPermission();
}
}
else
{
// Code for Below 23 API Oriented Device
// Create a common Method for both
}
Now adding checkPermission() and requestPermission()
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(Your_Activity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(Your_Activity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(Your_Activity.this, "Write External Storage permission allows us to do store images. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(Your_Activity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("value", "Permission Granted, Now you can use local drive .");
} else {
Log.e("value", "Permission Denied, You cannot use local drive .");
}
break;
}
}
I have problems when i use some code from Capture Image from Camera and Display in Activity and https://developer.android.com/training/camera/photobasics.html
First, this is in MainActivity.java. I create onClickevent when user press button "snap"
Button snap = (Button) findViewById(R.id.button3);
snap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent start_cam = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File path = null;
try {
path = createImageFile();
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
}
if(path!=null) {
start_cam.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(path));
startActivityForResult(start_cam, 1);
}
}
});
Next, i add createImageFile() method
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, // prefix
".jpg", // suffix
storageDir // directory
);
// Save a file: path for use with ACTION_VIEW intents
root_file = "file:" + image.getAbsolutePath();
return image;
}
Last part, I add onActivityResult()
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
try {
m = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(root_file));
try {
view.setImageBitmap(m);
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I also add heading in my AndroidManifest.xml
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
After, i use this feature in android emulator API19 Nexus_one API19 (take a photo). The dialog appears and said "java.lang.nullPointerException".
I don't know why this problem appears. I think it may be my emulator or code.