error calling MediaStore.ACTION_VIDEO_CAPTURE - android

i'm trying to create an app that allows video recording. i know that using MediaStore.ACTION_IMAGE_CAPTURE, it actually calls the camera system from my app and after taking the picture, it will return to my app with result.
while using the code, i found a MediaStore.ACTION_VIDEO_CAPTURE. which i assume it will camera but in video mode, rather then image capturing mode.
the code that i used for calling the camera in video mode:
Intent takeVideoFromCameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Uri mUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "/Record/vid_"+ String.valueOf(System.currentTimeMillis()) + ".mp4"));
takeVideoFromCameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mUri);
startActivityForResult(takeVideoFromCameraIntent, RESULT_OK);
when i run the app with a real device, it does call the camera in video mode and also allows video recording. however, when i press the record button to finish recording, it returns to my app with a force close message saying that the camera is not responding.
at 1st, i thought that the video has not been captured, but when i searched for the file, it actually exist.
then, i thought its my onActivityResult method that causes the problem, but after i comment it with /* ... */ , it still have the same problem. but there isn't any details shown in LogCat.

i realize that i got the error because i'm adding extra to it. what i just needed to do is
Intent takeVideoFromCameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(takeVideoFromCameraIntent, 1111);
then, add an onActivityResult, with the request code == 1111 (depends on what you entered) and retrieve the last modified file that consist of the extension ".mp4" from the default folder of camera "DCIM/Camera"
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1111)//cam
{
File folder = new File(Environment.getExternalStorageDirectory(), "/DCIM/Camera");
long folderModi = folder.lastModified();
FilenameFilter filter = new FilenameFilter()
{
public boolean accept(File dir, String name)
{
return (name.endsWith(mp4));
}
};
File[] folderList = folder.listFiles(filter);
String recentName = "";
for(int i=0; i<folderList.length;i++)
{
long fileModi = folderList[i].lastModified();
if(folderModi == fileModi)
{
recentName = folderList[i].getName();
}
}
}
this way, i can get the name of the file and also do the modification (e.g renaming) with it.
hope this would help other people. =)

please,add your logcat.
For the video capture, i am using the MediaRecorder class, I suggest you tu use this.
If you are interested, i can give you the right code.

I think, your problem is resolved by using this code.
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
Use this code in an activity and also set some property in xml file.
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
If you have another problem, please reply me.

Related

Android Security Exception on imageView.setImageUri with album image Uri

The image source is a Uri which is stored in Firestore.
If a user saves their profile photo from either camera or album, it gets its Uri then stores as a string in the Firestore. There's no problem until this point.
I'll say the photo taken from Camera as CameraImage, and the photo chosen from the album as AlbumImage.
But when displaying the AlbumImage's Uri(as String) retrieved from Firestore, Security Exception is thrown.
Possible solutions I'm assuming are:
need to save the Uri in a different way.
need to load Uri in a different way.
Loding the image(error on this line):
iv_photo.setImageURI(Uri.parse(mUser.getPhotoString()));
Activity for result:
Intent selectIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
selectIntent.setType("image/*");
galleryResultLauncher.launch(selectIntent);
ActivityResultLauncher<Intent> galleryResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if(result.getResultCode() == Activity.RESULT_OK){
Uri selectedImg = result.getData().getData();
iv_photo.setImageURI(selectedImg);
mUri = selectedImg.toString();
}
}
});
Security Exception:
Permission Denial: opening provider com.google.android.apps.photos.contentprovider.impl.MediaContentProvider from ProcessRecord{c7fba1f 23624:com.example.seanlee_thefootballgallery_2201/u0a165} (pid=23624, uid=10165) that is not exported from UID 10118
AlbumImage URIs is similar to this.
content://com.example.seanlee_thefootballgallery_2201/app_images/10-02-2022-09-17-01.jpg
CameraImage URIs is similar to this.
content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F25/ORIGINAL/NONE/image%2Fjpeg/967503137
Manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
you can upload your photo to firebase storage first, you can read this upload file to firebase storage .after that you can add more code like this to get Url from storage
StorageReference storageReference = FirebaseStorage.getInstance().getReference().child()
//that child is up to you
storageReference.putFile(imageUri).addOnCompleteListener(task ->
storageReference.getDownloadUrl().addOnSuccessListener(uri -> {
String url = uri.toString();
}));
after that you can save url into firestore. if you want show it into your app you should get url from firestore first after that download it from firebase storage. for download file you can read this download file from firebase storage
hope it can solve your problem :)
Solved.
Changing intent action from ACTION_PICK to ACTION_OPEN_DOCUMENT solved the issue.

Unable to open captured photo in Android's default image viewer using photo's URI

One of the features of my app is to allow user to assign a photo of an item stored in a DB. This could be done by either taking a new photo with the in-built camera or choosing an image from the library. Then app resizes the captured image, retrieve a full size image URI and store both in a DB. Full size image URI is stored for a later use in case user wants to load a full size image with the default image viewer. Everything works fine except viewer is unable to load image from the captured image URI right after the photo is taken, but it is possible to load the same image only when it is chosen from the library.
Ok here is the code:
manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.packagename.inventoryapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/fileprovider" />
</provider>
fileprovider.xml
<external-files-path
name="images"
path="Pictures" />
Handle the camera:
#NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
public void onLaunchCamera(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoFileName = String.valueOf(System.currentTimeMillis()) + ".jpg";
photoFile = getPhotoFileUri(photoFileName);
Uri fileProvider = FileProvider.getUriForFile(this,
ProductContract.CONTENT_AUTHORITY + ".fileprovider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
}
public File getPhotoFileUri(String fileName){
File mediaStorageDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), APP_TAG);
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
Log.d(APP_TAG, "failed to create directory");
}
return new File(mediaStorageDir.getPath() + File.separator + fileName);
}
onActivtiyResult (takenImage - global Bitmap variable;
mPicUri - global Uri variable):
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
/* User chose to take a new photo */
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
File takenPhotoUri = getPhotoFileUri(photoFileName);
mPicUri = FileProvider.getUriForFile
(this, ProductContract.CONTENT_AUTHORITY + ".fileprovider", photoFile);
Bitmap fullSizeImage = BitmapFactory.decodeFile(takenPhotoUri.getAbsolutePath());
takenImage = BitmapScaler.scaleToFitWidth
(fullSizeImage, mProductImageView.getWidth() / 100 * 50);
} else { // Result was a failure
Toast.makeText(this, getString(R.string.no_picture_taken),
Toast.LENGTH_SHORT).show();
}
}
/* User chose to take an an existing photo from the gallery */
else if (requestCode == PICK_PHOTO_CODE){
if (resultCode == RESULT_OK) {
mPicUri = data.getData();
try {
Bitmap fullSizeImage = MediaStore.Images.Media.getBitmap
(getContentResolver(), mPicUri);
takenImage = BitmapScaler.scaleToFitWidth
(fullSizeImage, mProductImageView.getWidth() / 100 * 60);
} catch (IOException e) {
e.printStackTrace();
}
}
}
mProductImageView.setImageBitmap(takenImage);
/* Save image and it's URi to the database */
if (takenImage != null){
ContentValues values = new ContentValues();
values.put(ProductEntry.COLUMN_IMAGE, DbBitmapUtility.getBytesArray(takenImage));
values.put(ProductEntry.COLUMN_IMAGE_URL, mPicUri.toString());
int rows = getContentResolver().update(mProductUri, values, null, null);
}
}
Open default image image viewer to load a full size image from Uri:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(mPicUri);
startActivity(intent);
I realise that the problem is in Uri path of a captured photo. When I retrieve it in the above way I get something like:
content://com.packagename.inventoryapp.fileprovider/images/InventoryApp/1526632674426.jpg
and Image viewer is launching with the blank screen indicating it is searching for the image with no success.
I tried to get mPicUri with getAbsolutePath() method that leads to the app crashing on launching the intent with that message:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=/storage/emulated/0/Android/data/com.packagename.inventoryapp/files/Pictures/InventoryApp/1526635391354.jpg }
On the contrary taking image from the existing library works fine and image Uri looks like:
content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F2504/ORIGINAL/NONE/1872082740
So the question is it possible to somehow retrieve captured image Uri that is not app private and could be red by image viewer?
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=/storage/emulated/0/Android/data/com.packagename.inventoryapp/files/Pictures/InventoryApp/1526635391354.jpg }
That is not a valid Uri.
A Uri has a scheme. Yours does not. Yours resembles a bare filesystem path. In principle, you could convert that to a Uri using Uri.fromFile().
However, on Android 7.0+, using such a Uri will fail with a FileUriExposedException.
Instead, use the File with FileProvider.getUriForFile(), and provide that Uri to your ACTION_VIEW Intent. Be sure to also call addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) on that Intent, to allow third-party apps to read the content identified by that Uri.

Unable to capture image using camera intent in samsung note 3

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

How to change the directory of SquareCamera library?

I am using SquareCamera library (https://github.com/boxme/SquareCamera) for taking square picture.The problem I am facing is that SquareCamera is creating its own folder where taken pics are getting stored. I want these pics to store in my own folder. I don't know how to achieve that. I am very new to android. Below is the code where instead of default camera I am calling its own class.
public void onLaunchCamera(View view) {
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(this,CameraActivity.class);
// Start the image capture intent to take photo
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
And this is the onActivityResult method
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Uri takenPhotoUri = data.getData();
Bitmap takenImage = BitmapFactory.decodeFile(takenPhotoUri.getPath());
imageView.setImageBitmap(takenImage);
I thought about saving this bitmap into my own folder but I couldn't think how to delete the created directory of SquareCamera.
So I found the solution. I added the library as a module in my app. Referring (https://www.youtube.com/watch?v=1MyBO9z7ojk). And there I changed the source code a little bit and now it's working perfect.
I'm a bit long in the tooth at Android and am not 100% with the new Uri methods of file access enforced since KitKat. For conventional file access you can get a private writeable file using.
private static final File OUTPUT_DIR = Environment.getExternalStorageDirectory();
FileOutputStream fos;
void yourMethodBeginsHere() {
String outputPath = new File(OUTPUT_DIR, "test.png").toString();
try {
fos = new FileOutputStream(outputPath, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Work with file
}
If you need a truly external file path please refer to the excellent answer already existing at https://stackoverflow.com/a/26765884/5353361 which deals fully with the new Uri based system of permissions and the integrated file explorer.

Intent does not set the camera parameters

I am opening camera app as external intent from my applications. I am using following code to invoke the camera and following are my conditions:
It should open the front camera.
Highest picture quality.
Flash light has to be on
Following is my code:
Intent action = new Intent("android.media.action.IMAGE_CAPTURE");
action.putExtra("android.intent.extras.CAMERA_FACING", 1);
action.putExtra("android.intent.extras.FLASH_MODE_ON", 1);
action.putExtra("android.intent.extras.QUALITY_HIGH", 1);
Now, it does open the front camera BUT it does not turn on the flash and it does not set the picture quality to high.
My Manifest file's permission section looks like following:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />
is there anything that I am missing?
Unfortunately, when using the camera with Intent, the only extra parameter you can set is
MediaStore.EXTRA_OUTPUT
Eg
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
Which allows you to map where the Camera application will store the image.
Camera Facing intent extra can sometimes work:
action.putExtra("android.intent.extras.CAMERA_FACING", 1);
Looking in the android source files, there are some "test" methods that are in the Util class file but not officially documented:
(Util)
private static final String EXTRAS_CAMERA_FACING =
"android.intent.extras.CAMERA_FACING";
// This is for test only. Allow the camera to launch the specific camera.
public static int getCameraFacingIntentExtras(Activity currentActivity) {
int cameraId = -1;
int intentCameraId =
currentActivity.getIntent().getIntExtra(Util.EXTRAS_CAMERA_FACING, -1);
if (isFrontCameraIntent(intentCameraId)) {
// Check if the front camera exist
int frontCameraId = CameraHolder.instance().getFrontCameraId();
if (frontCameraId != -1) {
cameraId = frontCameraId;
}
} else if (isBackCameraIntent(intentCameraId)) {
// Check if the back camera exist
int backCameraId = CameraHolder.instance().getBackCameraId();
if (backCameraId != -1) {
cameraId = backCameraId;
}
}
return cameraId;
}
And in the photomodule, the following method is used:
(PhotoModule)
private int getPreferredCameraId(ComboPreferences preferences) {
int intentCameraId = Util.getCameraFacingIntentExtras(mActivity);
if (intentCameraId != -1) {
// Testing purpose. Launch a specific camera through the intent
// extras.
return intentCameraId;
} else {
return CameraSettings.readPreferredCameraId(preferences);
}
}
And when the camera app initialises the photo mode, it calls this method to check which camera to use:
mCameraId = getPreferredCameraId(mPreferences);
intent.putExtra("android.intent.extras.CAMERA_FACING", android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
this is an intent to start capture with the front camera instead of the default rear camera.
this works as it is used in this popular cordova plugin in this link at line 145 :
https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin/blob/master/src/android/nl/xservices/plugins/videocaptureplus/VideoCapturePlus.java
hope this helps anyone facing the same problem.
also do you know if you can set an intent to disable the camera controls(filters,switch between cameras..etc) , so that they doesn't show ?

Categories

Resources