Output Uri from this Android crop image library? - android

I'm trying to implement SoundCloud's image crop to my app. Here's what I'm doing so far:
call Crop.pickImage((Activity) this) to pick an image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Crop.REQUEST_PICK && resultCode == RESULT_OK) {
Uri inputUri = data.getData();
new Crop(inputUri).output(outputUri).asSquare().start((Activity) context);
}
else if (requestCode == Crop.REQUEST_CROP && resultCode == RESULT_OK) {
Uri cropped = data.getData();
}
}
At this point I don't know what should be the outputUri. I can just use the same inputUri as the output, but that would overwrite the original image file. I want to create a new file instead. But I can't create new Uri since Android Studio tells me the newly initialized Uri is abstract and can't be used.

I used following methods for my cropping image library for URI creation as well. Hopefully it will helps you:
private void fileSaving(){
String stateEnvironment = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(stateEnvironment)) {
mFileTemp = ChatUtils.getOutputMediaFile(101);//new File(Environment.getExternalStorageDirectory(), TEMP_PHOTO_FILE_NAME);
} else {
mFileTemp = new File(getFilesDir(), sTEMP_PHOTO_FILE_NAME);
}
}
private void takePicture() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
Uri mImageCaptureUri = null;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mImageCaptureUri = Uri.fromFile(mFileTemp);
} else {
// mImageCaptureUri =
// InternalStorageContentProvider.CONTENT_URI;
}
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
intent.putExtra("return-data", true);
startActivityForResult(intent, mREQUEST_CODE_TAKE_PICTURE);
} catch (ActivityNotFoundException e) {
}
}

Related

MediaStore.ACTION_VIDEO_CAPTURE not saving the video in Nougat 7.0

Hi i have been trying to record and save a video from Nougat 7.0 using intent, I can record a video but its not getting saved in the device storage. I even used FileProvider to avoid 'FileUriExposedException'. But when it comes for Capturing Images it is getting saved in the below specified path.
Here is my code.
private Uri imageUri;
private File imageFile = null;
public File videoFilePath() {
return new File(getDefaultCameraPath(), "Video_" + System.currentTimeMillis() + ".mp4");
}
private void callCameraIntent(){
Intent cameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
imageFile = videoFilePath();
imageUri = FileProvider.getUriForFile(CreatePostActivity.this, BuildConfig.APPLICATION_ID + ".provider", imageFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(cameraIntent, 2);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_CANCELED) {
//Here it returns imageFile does not exist so it skips the if statement
if (resultCode == Activity.RESULT_OK && requestCode == 2 && imageFile != null && imageFile.exists()) {
}
}
}
The above code works well for all the pre-Nougat version. Can anyone provide me a better solution to record the video and save in device storage.
here is the solution !
If your targetSdkVersion is 24 or higher, we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps.
Stackoverflow link:
android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
also you should check the required permission android.Manifest.permission.CAMERA
File Video_folder = new File(Environment.getExternalStorageDirectory(),
"Sample/Videos")
File videoMediaFile=null;
private void DispatchVideoRecordIntent() {
try {
videoMediaFile = File.createTempFile(
"VID_" + System.currentTimeMillis(),
".mp4",
Video_folder
);
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(videoMediaFile));
startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
} catch (Exception e) {
Log.e("Image Capturing", e.toString());
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == REQUEST_VIDEO_CAPTURE) {
if (!TextUtils.isEmpty(videoMediaFile.getAbsolutePath())) {
// videoMediaFile.getAbsolutePath() is your file path
} else {
Toast.makeText(this, "Unable to capture video.", Toast.LENGTH_SHORT).show();
}
}

Android - Check button after taking picture using camera doesn't do anything

So.. I'm trying to choose a picture using both camera and gallery, then pass it to an external library to crop image.
The problem lies with saving image after taking it with the camera. I've managed to get the camera running and take an image with it, then it display the image and the default Android Ok and back button. The Ok button responds to touch (as touch effect can be seen) but it doesn't do anything.
Here's the code for getting the file ready to save
date = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyyyyHHmmss");
dateString = simpleDateFormat.format(date);
dateBuilder = new StringBuilder().append(dateString).append(".jpg");
SAMPLE_CROPPED_IMAGE_NAME = dateBuilder.toString();
final String cameraDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/SamplePics/";
newDir = new File(cameraDir);
newDir.mkdirs();
This is the code for camera function
RelativeLayout.OnClickListener photoCameraWrapperHandler = new RelativeLayout.OnClickListener(){
#Override
public void onClick(View v) {
//Intent intent = new Intent(SignupStepThreeActivity.this, SignupStepFourActivity.class);
//startActivity(intent);
String cameraFile = SAMPLE_CROPPED_IMAGE_NAME;
newFile = new File(cameraFile);
try {
newFile.createNewFile();
}
catch (IOException e)
{
}
Uri outputFileUri = Uri.fromFile(newFile);
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
};
And here's the onActivityResult :
private static final int CAMERA_REQUEST = 1888;
private static final int REQUEST_SELECT_PICTURE = 0x01;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_SELECT_PICTURE || requestCode == CAMERA_REQUEST) {
final Uri selectedUri = data.getData();
if (selectedUri != null) {
startCropActivity(data.getData());
} else {
Toast.makeText(SignupStepThreeActivity.this, R.string.toast_cannot_retrieve_selected_image, Toast.LENGTH_SHORT).show();
}
} else if (requestCode == UCrop.REQUEST_CROP) {
handleCropResult(data);
}
}
if (resultCode == UCrop.RESULT_ERROR) {
handleCropError(data);
}
}
Several updates before, it crashes when I click on camera button, I suspected it was because of I kind of take the uri of the image from storage but I haven't created the folder. Now I finally managed to get the camera running but not saving. The create folder part works tho..
public String getCamerPath(Context context) {
SharedPreferences prefs = context.getSharedPreferences("setCamerPath", 0);
String value = prefs.getString("getCamerPath", "");
return value;
}
public void setCamerPath(Context context, String value)
{
SharedPreferences prefs = context.getSharedPreferences("setCamerPath", 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("getCamerPath", value);
editor.commit();
}
Uri outputFileUri = Uri.fromFile(newFile);
setCamerPath(this, outputFileUri.getPath());
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_SELECT_PICTURE || requestCode == CAMERA_REQUEST) {
startCropActivity(getCamerPath(this));
} else if (requestCode == UCrop.REQUEST_CROP) {
handleCropResult(data);
}
}
if (resultCode == UCrop.RESULT_ERROR) {
handleCropError(data);
}
}
In the camera OnClickListener, I commented some stuffs like this :
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
//Uri outputFileUri = Uri.fromFile(newFile);
//cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
//setCamerPath(SignupStepThreeActivity.this, outputFileUri.getPath());
startActivityForResult(cameraIntent, CAMERA_REQUEST);
In my onActivityResult, I've modified a part of CAMERA_REQUEST :
else if (requestCode == CAMERA_REQUEST) {
Uri capturedImageUri = data.getData();
Bitmap bitmap;
if (capturedImageUri != null) {
startCropActivity(capturedImageUri);
} else {
Toast.makeText(SignupStepThreeActivity.this, R.string.toast_cannot_retrieve_selected_image, Toast.LENGTH_SHORT).show();
Bundle extras = data.getExtras();
bitmap = (Bitmap) extras.get("data");
Uri imageUri = getImageUri(SignupStepThreeActivity.this, bitmap);
startCropActivity(imageUri);
}
}
So basically as I've been reading around for the past 4 hours, data is Intent. It will always be not null BUT will not always contain Uri itself for the image. Because I need the Uri for a library I'm using, I use a method called getImageUri from another Stackoverflow answer.
public static Uri getImageUri(Context inContext, Bitmap inImage)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
Now the problem lies with bitmap image quality after taking the image, I'm going to tinker around with it and be back with an update.
This can also resolve the problem
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("camera", "onSaveInstance");
// save file url in bundle as it will be null on screen orientation
// changes
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.d("camera", "onRestoreInstance");
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}

Android onclick radio button camera intent not working

i have a radio button. when i click on radio button camera intent is opened after taking a image using camera. image is not updating to image view.
i have used all permissions in my manifest file.
RB_PhotoStatus
.setOnCheckedChangeListener(new android.widget.RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group,
int checkedId) {
switch (checkedId) {
case R.id.yes:
//photoCollected = "Yes";
// create intent with ACTION_IMAGE_CAPTURE action
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
break;
case R.id.no:
photoCollected = "No";
break;
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bp = (Bitmap) data.getExtras().get("data");
imageView1.setImageBitmap(bp);
}
Taking Photos Simply!
This answer explains how to capture photos using an existing camera application.
<manifest ... >
<uses-feature android:name="android.hardware.camera"
android:required="true" />
...
</manifest>
Request for camera application.
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
Camera return intent with data on Activity override function onActivityResult as bellow:-
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
For more info follows this link given bellow:
http://developer.android.com/training/camera/photobasics.html
It doesn't work because Camera Intent won't return the entire BitMap, but only the reference (Uri) to the created file.
Uri selectedImage = data.getData();
From this Uri you may re-load the BitMap using BitmapFactory.decodeFile
On radiobuttonclick();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
onActivityResult();
Uri originalUri = data.getData();
imageview.setImageURI(originalUri);
And If you want to get bitmap then
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), originalUri);
private String mCurrentPhotoPath;
final String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
final File image = create_directory();
// Save a file: path for use with ACTION_VIEW intents
try {
mCurrentPhotoPath = image.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
if (image != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
} else {
snackbar = Snackbar.make(findViewById(android.R.id.content), "An error has occurred", Snackbar.LENGTH_SHORT);
snackbar.setAction("Dismiss", clickListener);
snackbar.show();
}
}
}
public File create_directory() {
// Create an image file name
final String imageFileName;
final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
final String user_id = "1_";
imageFileName = user_id + timeStamp + "_";
final String proj_name = "test";
final String folder_timeStamp = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH).format(new Date());
final String path = "/TEST/" + proj_name + "/" + folder_timeStamp;
final File dr = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), path);
if (!dr.exists()) {
dr.mkdirs();
}
File image = null;
try {
image = File.createTempFile(imageFileName, ".jpg", dr);
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK){
//do something with the image which is stored in mCurrentPhotoPath
}
}
}

Cropper returns null Uri

My app has possibility to change user avatar (with latter uploading it to web service). But on some devices Cropper ("com.android.camera.action.CROP" Intent) starts, but returns null Uri. Could u point me what i've done wrong?
1st user picks photo with:
public static void pickPhoto(final Context context) {
Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
pickImageIntent.setType("image/*");
((ActionBarActivity) context).startActivityForResult(Intent.createChooser(pickImageIntent, "Select Avatar"), SettingsActivity.REQUEST_CODE_PICK_AVATAR);
}
Then after activity get's RESULT_OK (selected image uri) - it starts cropper:
public static void startCropper(final Context context, final Uri imageToCrop) {
final Intent intent = new Intent("com.android.camera.action.CROP");
intent.setData(imageToCrop);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("noFaceDetection", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context)));
intent.putExtra("return-data", true);
((ActionBarActivity) context).startActivityForResult(intent, SettingsActivity.REQUEST_CODE_CROP_AVATAR);
}
which returns RESULT_OK with null getData():
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_CROP_AVATAR && resultCode == RESULT_OK) {
Uri uri = data.getData(); // uri is null on some devices
}
}
My getTempFile method:
public static File getTempFile(Context context) {
File cacheDir;
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
cacheDir = context.getCacheDir();
} else {
cacheDir = context.getExternalCacheDir();
}
File file = new File(cacheDir, "temp_avatar.jpg");
try {
file.createNewFile();
} catch (IOException e) {
}
return file;
}
As mentioned in question comments by greenapps, it's just need to place additional check in onActivityResult() if uri is null and then getExtra("data"), like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_CROP_AVATAR && resultCode == RESULT_OK) {
Uri uri = data.getData();
if (null != uri) {
// do something with uri
} else {
Bitmap bitmap = data.getExtra("data");
// get uri from bitmap and do something with uri
}
}
}
Code tested in my app and works fine.

Android camera capture activity returns null Uri

This code worked on samsung before but now that i'm using Nexus One with Android 2.3.6, it's crashing as soon as I take a picture and click ok or choose a photo from gallery. Stacktrace shows a null pointer exception on the Uri.
My code for the activating the camera is as follows:
public void activateCamera(View view){
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// start the image capture Intent
startActivityForResult(i, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == CHOOSE_IMAGE_ACTIVITY_REQUEST_CODE || requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
&& resultCode == RESULT_OK && null != data) {
selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap bits = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = inSampleSize;
try {
bits = BitmapFactory.decodeStream(new FileInputStream(picturePath),null,options);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Any idea what could be the problem?
Thanks!
You have to tell the camera, where to save the picture and remeber the uri yourself:
private Uri mMakePhotoUri;
private File createImageFile() {
// return a File object for your image.
}
private void makePhoto() {
try {
File f = createImageFile();
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mMakePhotoUri = Uri.fromFile(f);
i.putExtra(MediaStore.EXTRA_OUTPUT, mMakePhotoUri);
startActivityForResult(i, REQUEST_MAKE_PHOTO);
} catch (IOException e) {
Log.e(TAG, "IO error", e);
Toast.makeText(getActivity(), R.string.error_writing_image, Toast.LENGTH_LONG).show();
}
}
#Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_MAKE_PHOTO:
if (resultCode == Activity.RESULT_OK) {
// do something with mMakePhotoUri
}
return;
default: // do nothing
super.onActivityResult(requestCode, resultCode, data);
}
}
You should save the value of mMakePhotoUri over instance states withing onCreate() and onSaveInstanceState().
Inject this extra into the Intent that called onActivityResult and the system will do all the heavy lifting for you.
File f = createImageFile();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
Doing this makes it as easy as this to retrieve the photo as a bitmap.
private void handleSmallCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(mImageBitmap);
}
dont pass any extras, just define the path where you have placed or saved the file directly in onActivityResult
public void openCamera() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
file = createImageFile();
boolean isDirectoryCreated = file.getParentFile().mkdirs();
Log.d("", "openCamera: isDirectoryCreated: " + isDirectoryCreated);
if (Build.VERSION.SDK_INT >= 23) {
tempFileUri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
"com.scanlibrary.provider", // As defined in Manifest
file);
} else {
tempFileUri = Uri.fromFile(file);
}
try
{
cameraIntent.putExtra("return-data", true);
startActivityForResult(cameraIntent, ScanConstants.START_CAMERA_REQUEST_CODE);
}
catch (Exception e)
{
}
}
private File createImageFile() {
clearTempImages();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new
Date());
File file = new File(ScanConstants.IMAGE_PATH, "IMG_" + timeStamp +
".jpg");
fileUri = Uri.fromFile(file);
return file;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bitmap = null ;
if (resultCode == Activity.RESULT_OK ) {
try {
if (Build.VERSION.SDK_INT >= 23) {
tempFileUri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
"com.scanlibrary.provider", // As defined in Manifest
file);
} else {
tempFileUri = Uri.fromFile(file);
}
bitmap = getBitmap(tempFileUri);
bitmap = getBitmap(data.getData());
} catch (Exception e) {
e.printStackTrace();
}
} else {
getActivity().finish();
}
if (bitmap != null) {
postImagePick(bitmap);
}
}

Categories

Resources