i have a problem with code of take a picture and save. It crash when i launchCamera().
Can you help me please?
private void launchCamera() {
try {
mOutputFile = File.createTempFile("prova", null);
Intent intentCamera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(mOutputFile));
startActivityForResult(intentCamera, CAMERA_REQUEST);
} catch (Exception e) {
Toast t = Toast.makeText(this, "ERROR:\n" + e.toString(), Toast.LENGTH_LONG);
t.show();
}
}
I am using this piece of code try it out :
/**
* This method is used to start the camera activity and save the image taken as the imagename passed
*
* #param imagename : this is the name of the image which will be saved
*/
private void clickPicture(String imagename) {
Intent getCameraImage = new Intent("android.media.action.IMAGE_CAPTURE");
File cameraFolder;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cameraFolder = new File(android.os.Environment.getExternalStorageDirectory(),"myfolder/");
else
cameraFolder= context.getCacheDir();
if(!cameraFolder.exists())
cameraFolder.mkdirs();
String imageFileName = imagename;
File photo = new File(Environment.getExternalStorageDirectory(), "myfolder/" + imageFileName);
getCameraImage.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
Uri.fromFile(photo);
startActivityForResult(getCameraImage, 1);
}
and add the permisson in your manifest file :
<uses-permission android:name="android.permission.CAMERA" ></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Maybe you didn't added the necessary permissions in the manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Also I would suggest you to go over this blog post I wrote on this topic of taking a picture using the build-in Camera Activity:
Take Picture with build in Camera Activity
To access the device camera, you must declare the CAMERA permission in your Android Manifest
Related
I'm trying to capture a new image using the camera and after that store it in the external storage.
I followed this tutorial Save the full-size photo and this Add the photo to a gallery but after running the app, The camera starts and captured the image successfully, But when I go to the gallery, Can't find the image who captured via camera!
//I changed this from com.example.android.fileprovider to com.test.app.fileprovider
android:authorities="com.test.app.fileprovider"
//I changed this line Uri photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile); to below code
Uri photoURI = FileProvider.getUriForFile(this, "com.test.app.fileprovider", photoFile);
//I added this permission
<uses-permission android:name="android.permission.CAMERA" />
//I enabled storage permission read and write
//I tested the codes on API 24
//minSdkVersion 21
Manifests
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.app">
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.test.app.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application>
</manifest>
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures" />
</paths>
MainActivity
public class MainActivity extends AppCompatActivity {
String currentPhotoPath;
int REQUEST_IMAGE_CAPTURE = 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.installSplashScreen(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dispatchTakePictureIntent();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable #org.jetbrains.annotations.Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.test.app.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
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 = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
}
Additional Question: What is the difference between this tutorial Save the full-size photo and this tutorial Add the photo to a gallery?
The best answer will take +50 bounty from this account if I reached 50 points, Otherwise, I'll give him the bounty from my other account after 2 days.
Your file will not be scanned by the MediaStore and hence will not be visible in Gallery apps as Gallery apps mostly get their info from MediaStore.
getExternalFilesDir() is a location private for your app and the MediaStore respects that.
How can I capture a new image using the camera and after that store it in the external storage?
Wrong problem description.
Once the camera app took the picture the camera app will save the picture to the file indicated by the file provider. There is nothing to do more then.
So before starting the camera and even before using FileProvider you should have determined a suitable location for your file and builded a nice uri for that file.
You have at least two options.
Use MediaStore to get an uri for a file in public DCIM or Pictures directory.
Use getExternalStoragePublicDirectory() with FileProvider to get an uri for a file in the same public directories.
In my App, there is provision of taking picture through Camera and send it for Crop but when the Camera App opens with the sent image and the user crops and clicks on OK, a toast is displayed by the Camera App,
"Unable to save cropped images"
Here is the code I have written for it:
public static void sendImageForCrop(final Activity activity, final Uri mImageCaptureUri){
final ArrayList<CropOption> cropOptions = new ArrayList<>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = activity.getPackageManager().queryIntentActivities(
intent, 0);
int size = list.size();
if (size == 0) {
Toast.makeText(activity, "Can not find image crop app",
Toast.LENGTH_SHORT).show();
} else {
//intent.setData(mImageCaptureUri);
intent.setDataAndType(mImageCaptureUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
try{
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File.createTempFile("temp", null, activity.getCacheDir())));
}catch(IOException ioe){
// It is unfortunate that the Photo can't be cropped.
// Show a Toast for this.
Toast.makeText(activity, "The photo couldn't be saved :(. Try clearing the App data.", Toast.LENGTH_SHORT).show();
return;
}
activity.startActivityForResult(i, CROP_FROM_CAMERA);
}
}
And here is the toString() of the Intent object:
Intent { act=com.android.camera.action.CROP dat=file:///storage/emulated/0/Snap_1508218098533.jpg typ=image/* flg=0x2 (has extras) }
What might be the problem here?
EDIT: As requested, here is the manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.example"
android:versionCode="156"
android:versionName="1.2.54">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>
<uses-sdk tools:overrideLibrary="com.braintreepayments.api.core,com.android.volley,com.paypal.android.sdk.onetouch.core,com.braintreepayments.api" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.location.network"
android:required="false" />
<uses-feature
android:name="android.hardware.location"
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<uses-feature
android:name="android.hardware.microphone"
android:required="false" />
<!-- Tell the system this app requires OpenGL ES 2.0. -->
<uses-feature
android:glEsVersion="0x00015000"
android:required="true" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<application
android:name="com.example.example.UILApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#drawable/applicationlogo"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/Theme.MyTheme">
<!-- List of Activities here -->
<provider
android:name=".provider.GenericFileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
</application>
</manifest>
I think the problem is may be with the path where your trying to save,
try to use like below
public void choosePhoto(View view) {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", int_Width_crop);
intent.putExtra("outputY", int_Height_crop);
intent.putExtra("scale", false);
intent.putExtra("return-data", true);
File photo = new File(Environment.getExternalStorageDirectory(), "cropped_image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, CHOOSE_PICTURE);
}
I had same problem but I fixed by changing the path of saved image directory as below -:
File croppedImageDirectory = new File(Environment.getExternalStorageDirectory()+"/croppedImage");
Or, see this answer may help you-: stackoverflow.com/a/1976115
May help you
I know this would be a considered a hack approach by many of you but it works!
intent.putExtra(MediaStore.EXTRA_OUTPUT, (String)null);
Reasoning
Well, I looked up the source of Gallery App in MarshMallow(one of the places the crop was failing; other was the Photos App) and found this method that handles a CROP request:
private void saveOutput(Bitmap croppedImage) {
if (mSaveUri != null) {
OutputStream outputStream = null;
try {
outputStream = mContentResolver.openOutputStream(mSaveUri);
if (outputStream != null) {
croppedImage.compress(mOutputFormat, 75, outputStream);
}
} catch (IOException ex) {
// TODO: report error to caller
Log.e(TAG, "Cannot open file: " + mSaveUri, ex);
} finally {
Util.closeSilently(outputStream);
}
Bundle extras = new Bundle();
setResult(RESULT_OK, new Intent(mSaveUri.toString())
.putExtras(extras));
} else if (mSetWallpaper) {
try {
WallpaperManager.getInstance(this).setBitmap(croppedImage);
setResult(RESULT_OK);
} catch (IOException e) {
Log.e(TAG, "Failed to set wallpaper.", e);
setResult(RESULT_CANCELED);
}
} else {
Bundle extras = new Bundle();
extras.putString("rect", mCrop.getCropRect().toString());
File oldPath = new File(mImage.getDataPath());
File directory = new File(oldPath.getParent());
int x = 0;
String fileName = oldPath.getName();
fileName = fileName.substring(0, fileName.lastIndexOf("."));
// Try file-1.jpg, file-2.jpg, ... until we find a filename which
// does not exist yet.
while (true) {
x += 1;
String candidate = directory.toString()
+ "/" + fileName + "-" + x + ".jpg";
boolean exists = (new File(candidate)).exists();
if (!exists) {
break;
}
}
try {
int[] degree = new int[1];
Uri newUri = ImageManager.addImage(
mContentResolver,
mImage.getTitle(),
mImage.getDateTaken(),
null, // TODO this null is going to cause us to lose
// the location (gps).
directory.toString(), fileName + "-" + x + ".jpg",
croppedImage, null,
degree);
setResult(RESULT_OK, new Intent()
.setAction(newUri.toString())
.putExtras(extras));
} catch (Exception ex) {
// basically ignore this or put up
// some ui saying we failed
Log.e(TAG, "store image fail, continue anyway", ex);
}
}
final Bitmap b = croppedImage;
mHandler.post(new Runnable() {
public void run() {
mImageView.clear();
b.recycle();
}
});
finish();
}
You see the statement, if (mSaveUri != null) {. It handles the case where we provide a null Uri. The assumption is that the 3rd party App is likely to handle the case where we provide a null Uri.
Now, I tested it with a couple of Apps and it worked. But by no means, this solution is an ideal one.
It's may be an old question but I couldn't find any solution for my issue. So asking it again
I am trying to capture an image and store it in internal storage and after usage in my app I am deleting it. It is working fine in all devices but in Samsung Note 3.
private void captureImage() {
try {
if(photoPath!=null) {
new File(photoPath).delete();
photoPath = null;
}
//SET THE IMAGE NAME AND IMAGE PATH FOR THE CURRENT IMAGE
final Random random = new Random();
photoPath = getPath(this)+"/img" + String.valueOf(random.nextInt()) + ".jpg";
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final File imageStorage = new File(photoPath);
if (imageStorage != null) {
//to capture full image use URI otherwise use filepath
Uri photoURI = FileProvider.getUriForFile(this, "<<my path>>.fileprovider", imageStorage);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, Constants.ACTION_CAMERA_REQUEST);
}
}
catch (Throwable e) {
}
}
Is anything I am missing here. Please can anybody help me
In Manifeast.xml
<uses-permission android:name="android.permission.CAMERA" />
is mandatory in order to use the camera (I'm not using camera via Intent, I have a customize camera app)
<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.flash"
android:required="false" />
android:required="false" means Google Play will not prevent the application from being installed to devices that do not include these camera features - so the user having a device without camera and camera flash will be able to install the app from market.
http://developer.android.com/reference/android/hardware/Camera.html
The issue is to save image to the storage
This code worked fine, but not with Android 6 and N
What do I need to fix here?
Or as an option - using another example for saving to internal\external files
public void saveImage(Bitmap icon) {
File ff;
File file = new File(android.os.Environment.getExternalStorageDirectory(), "Folder Name");
ff = new File(file.getAbsolutePath() + file.separator + imageName + ".jpg");
if(ff.exists()){
Log.i("sharing", "File exist SD");
} else{
try {
File f = null;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
if (!file.exists()) {
file.mkdirs();
}
Log.i("sharing", "File exist Internal");
f = new File(file.getAbsolutePath() + file.separator + imageName + ".jpg");
}
FileOutputStream ostream = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
And permissions from Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Thanx
You should put the uses-permission-sdk-23 tag and set the permission you want.
Then
You should check whether the permission is granted or not by calling the checkSelfPermission and pass the permission name as argument
If the permission is not granted you should gain the permissions by calling the requestPermissions method and pass the permissions names as string array and the request code
After that
A dialog will be shown to user and ask them if the permission is granted or not
Then a interface onRequestPermissionResult will be called and you should implement this into your activity class
After that
You can gain access to the requested permissions if the user granted it
I added permissions for android sdk > 22
This code works perfectly
if (ContextCompat.checkSelfPermission(HomeActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(HomeActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23
);
}
I'm using the camera intent to captured images. But it's not showing when I check in on the gallery..
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
Intent intent_cam = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory() + File.separator + "App Photos");
Intent mediaScan = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
if (!imagesFolder.exists()) {
imagesFolder.mkdirs();
File image = new File(imagesFolder, "App_" + timeStamp + ".png");
Uri uriSavedImage = Uri.fromFile(image);
intent_cam.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
mediaScan.setData(uriSavedImage);
getActivity().sendBroadcast(mediaScan);
startActivityForResult(intent_cam, 0);
}
else if (imagesFolder.exists()) {
File image = new File(imagesFolder, "App_" + timeStamp + ".png");
Uri uriSavedImage = Uri.fromFile(image);
intent_cam.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
mediaScan.setData(uriSavedImage);
getActivity().sendBroadcast(mediaScan);
startActivityForResult(intent_cam, 0);
}
Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
And is it true that the sendBroadcast no longer works in API 19. (4.4)? Android How to use MediaScannerConnection scanFile
You are invoking the scan request before the picture has been captured. Recall that startActivityForResult() is asynchronous. Put your sendBroadcast() call in onActivityResult(), which will be triggered when the camera activity returns control to you.
This will work in all android versions:
MediaScannerConnection.scanFile(this, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);