Camera Shortcut onClick - android

Simple question. Is it possible to allow a button (preferably a FAB) to open a camera app, sort of as a short cut? This shortcut can either lead to the default camera, or lead to any downloaded camera apps.

Yes, it's possible.
You can create an implicit intent with action ACTION_IMAGE_CAPTURE.
eg:
File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", "image" + new Date().getTime() + ".png");
Uri imgUri = Uri.fromFile(file);
String imgPath = file.getAbsolutePath();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
startActivityForResult(intent, CAPTURE_IMAGE);
To handle the result:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_CANCELED) {
if (requestCode == CAPTURE_IMAGE) {
Bitmap resultAsBitmap = BitmapFactory.decodeFile(imgPath);
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
PS: Don't forget to add your permissions in manifest file.

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();
}
}

The IMAGE_CAPTURE can not return back in some android devices

I need to take photos in my application, this is the core codes:
tigger:
mPhotoToBeUpload = new File(mImageBasePath, System.currentTimeMillis() + ".jpg");
try {
mPhotoToBeUpload.mkdirs();
mPhotoToBeUpload.createNewFile();
} catch (IOException e) {
Log.e("xx",e.getMessage());
}
Uri outputFileUri = Uri.fromFile(mPhotoToBeUpload);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, Result_Code_Camera);
Result handler:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if (resultCode == RESULT_OK) {
Bitmap photoTaken = BitmapFactory.decodeFile(mPhotoToBeUpload.getAbsolutePath());
mImageView.setImageBitmap(photoTaken);
} else
}
However I found that these codes work in some devices but not in some others.
For example, they does not work in Nexus 4 and Nexus5.
While I saythey does not work,I mean that after I take a picture, and hit the OK button, I cannot get back to the previous activity:
It have no effect when I hit the OK(the icon inside the red circle).
What is the problem?
Upadte:
private final String mImageBasePath = Environment.getExternalStorageDirectory() + File.separator + IConstant.Application_Folder + File.separator + "photos";
mPhotoToBeUpload = new File(mImageBasePath, System.currentTimeMillis() + ".jpg");
Result: mPhotoToBeupLoad=/storage/emulated/0/myapp/photos/1395287647386.jpg
Show what is your path for mImageBasePath, because this problem mostly happen when the file path is invalid.
Solved by referring this question:Android ACTION_IMAGE_CAPTURE Intent
Instead of
Uri outputFileUri = Uri.fromFile(mPhotoToBeUpload);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, Result_Code_Camera);
Use:
URI mPhotoToBeUploadURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoToBeUploadURI);

Read/Write Image from local File

How do I read and write image to/from a local file in android?
I want to take an image from a file, save it in memory and then read it from file.
I am using this code to write image in file:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String fileName=GetFileName().replace('.', ' ')+".png";
File out = new File(Environment.getExternalStorageDirectory()+File.separator +fileName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(intent, REQUEST_IMAGE);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
wb.loadUrl(sendUrl);
if(requestCode == REQUEST_IMAGE && resultCode == Activity.RESULT_OK) {
String imgPath= data.getExtras().get("Uri").toString();
bm = BitmapFactory .decodeFile(imgPath);
}
}
How can I read the image back?
Try this---
Uri mUriSavedImage;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String fileName=GetFileName().replace('.', ' ')+".png";
File out = new File(Environment.getExternalStorageDirectory()+File.separator +fileName);
mUriSavedImage= Uri.fromFile(out);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mUriSavedImage);
startActivityForResult(intent, REQUEST_IMAGE);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
wb.loadUrl(sendUrl);
if(requestCode == REQUEST_IMAGE && resultCode == Activity.RESULT_OK) {
String imgPath= mUriSavedImage.getPath();
bm = BitmapFactory.decodeFile(imgPath);
}
}

Picture coming from camera or gallery?

I have an intent chooser that allows me to pick image from gallery or camera like this:
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT,null);
galleryIntent.setType("image/*");
galleryIntent.addCategory(Intent.CATEGORY_OPENABLE);
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, galleryIntent);
chooser.putExtra(Intent.EXTRA_TITLE, "title");
Intent[] intentArray = {cameraIntent};
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooser,REQUEST_CODE);
I want my onActivityResult method to be like this:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(Condition == picture_coming_from_gallery)
{
//my code here
}
else if(condition == picture_coming_from_camera)
{
//another code here
}
}
What is the condition that allows me to know which source my image is coming from?
Updated:
Now it's working and here is the solution:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
if(data.getData()!=null)
{
try
{
if (bitmap != null)
{
bitmap.recycle();
}
InputStream stream = getContentResolver().openInputStream(data.getData());
bitmap = BitmapFactory.decodeStream(stream);
stream.close();
imageView.setImageBitmap(bitmap);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
bitmap=(Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(bitmap);
}
super.onActivityResult(requestCode, resultCode, data);
}
}
Thank you for you help!
Although the current piece of code is a neat way of presenting options to choose from, I found that it was severely difficult to manage. At least in my use case it was. I need to store images taken off the Camera to process further in the Aviary SDK (if the user so chooses).
To that end, I would like to propose a workaround.
This does not address your question per se. But offers an alternative considering you need to know where the Image is coming from (Camera / Gallery).
AlertDialog.Builder builder = new AlertDialog.Builder(StatusUpdate.this);
builder.setTitle("Choose Image Source");
builder.setItems(new CharSequence[] {"Gallery", "Camera"},
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
// GET IMAGE FROM THE GALLERY
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
Intent chooser = Intent.createChooser(intent, "Choose a Picture");
startActivityForResult(chooser, ACTION_REQUEST_GALLERY);
break;
case 1:
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(),
"some_directory_to_save_images/");
else
cameraFolder= StatusUpdate.this.getCacheDir();
if(!cameraFolder.exists())
cameraFolder.mkdirs();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
String timeStamp = dateFormat.format(new Date());
String imageFileName = "picture_" + timeStamp + ".jpg";
File photo = new File(Environment.getExternalStorageDirectory(),
"some_directory_to_save_images/" + imageFileName);
getCameraImage.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
initialURI = Uri.fromFile(photo);
startActivityForResult(getCameraImage, ACTION_REQUEST_CAMERA);
break;
default:
break;
}
}
});
builder.show();
This is the result (I still maintain that you code gives a much better selection set, but again, not the simplest thing in your use case or in mine either):
Now you can process the result based on the source of the selection:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case ACTION_REQUEST_GALLERY:
break;
case ACTION_REQUEST_CAMERA:
break;
}
}
};
UPDATED:
Found it!! There is an answer here on SO that addresses exactly what you need. It is still a * workaround of sorts*. In the sense that it does not rely on different requestCodes. But works nonetheless.
Strange I missed it when I was stuck with this. :-(
NOTE: I am not posting the code here and am linking to it instead. All props go to the original author. :-)
You can distinguish by using REQUEST_CODE
private static final int PICK_FROM_CAMERA = 1;
private static final int PICK_FROM_GALLARY = 2;
/* For Image capture from camera */
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, PICK_FROM_CAMERA);
/* For Image capture from Gallary*/
startActivityForResult(new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI),
PICK_FROM_GALLARY);
}
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch (requestCode) {
case PICK_FROM_CAMERA:
if (resultCode == Activity.RESULT_OK) {
Bitmap bitmapImage = (Bitmap) intent.getExtras().get("data");
}
break;
case PICK_FROM_GALLARY:
if (resultCode == Activity.RESULT_OK) {
Uri mImageCaptureUri = intent.getData();
}
break;
}
}

com.android.camera Process NOT being Destroyed

I'm trying to capture an image with the android.provider.MediaStore.ACTION_IMAGE_CAPTURE and things seem to work fine, the only problem is that the process com.android.camera isn't being destroyed after returning and it is interfering with the running of the rest of the application.
So I'm wondering why it is not being destroyed and how I can destroy it once the capture is done? Thanks any help would be appreciated.
Here is my code:
private OnClickListener buttonCaptureListener = new OnClickListener(){
public void onClick(View v){
String path = Environment.getExternalStorageDirectory() + "/"+Long.toHexString(System.currentTimeMillis())+".jpg";
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra( MediaStore.EXTRA_OUTPUT, outputFileUri );
startActivityForResult(intent,SelectImagesActivity.REQUEST_CAPTURE);
}
};
Result handling:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == SelectImagesActivity.REQUEST_CAPTURE){
if(resultCode == RESULT_OK){
// display image and etc.
}
}
}
I also think it is normal action that process is not destroyed immediately.
And I suggest below code for explicit meaning.
it is different that appending a extra data -('return data', true)- into the intent.
private OnClickListener buttonCaptureListener = new OnClickListener(){
public void onClick(View v){
String path = Environment.getExternalStorageDirectory();
String file_name = Long.toHexString(System.currentTimeMillis())+".jpg";
File file = new File(path , file_name);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra( MediaStore.EXTRA_OUTPUT, outputFileUri );
intent.putExtra("return-data", true);
startActivityForResult(intent,SelectImagesActivity.REQUEST_CAPTURE);
}

Categories

Resources