when I crete TAKE PHOTO implicit intent, a intent chooser window appear properly. Unfortunatelly, it shows package names instead of application names. Any idea what I doing wrong? Thanks.
Everything is working (intent, camera app, image returned to onActivityResult, ...).
If there is only one camera app - no choose is shown and camera app is called directly (correct).
Camera application which I have installed are: default android camera, Google Camera.
Tested on 3 different samsung phones.
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(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.e(PoiDetailGalleryFragment.class.getSimpleName(), "Error occurred while creating the File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri fileUri = Uri.fromFile(photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takePictureIntent, REQUEST_PHOTO_CAPTURE);
}
}
}
I suppose this issue is linked with the Samsung devices, they don't show application name but the package name only.
the Google Nexus devices behave differently, they show the application name and the package name together.
Related
I am currently working on small part of my graduation work. I have to test out, how you can get the location of the user without the location permission.
One way is that the user gets asked to take a picture and when the Camera application has the permission to get the location, you can read out the EXIF-Data from the picture which was taken by the user.
I tested it out on multiple real devices (2x Android 9, 1x Android 6, 1x Android 7.1) and it works on these devices.
But if I use the emulator (The camera has the location permisson, location service is turned on, camera is tagging the location to the image) the Android EXIF interface can't read out any EXIF data.
If I take manually a photo with the Camera app and look at the details of the photo in the gallery, the location is saved.
Does anyone have experience with this issue?
EDIT:
The most important code:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.readoutexifwithoutpermissions",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private void readOutImageData() {
Log.i(TAG, currentPhotoPath);
try {
ExifInterface exif = new ExifInterface(currentPhotoPath);
File file = new File(currentPhotoPath);
Log.i(TAG, "size of file: " + file.length());
Log.i(TAG, "reading out something..." + exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
this.txtLatitude.setText(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
this.txtLongitude.setText(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
} catch (IOException e) {
e.printStackTrace();
}
}
private File createImageFile() throws IOException {
String imageFileName = "JPEG_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName,
".jpg",
storageDir
);
currentPhotoPath = image.getAbsolutePath();
return image;
}
SOLUTION:
I don't know why, but when you are using the Camera via Intent no additional information gets stored. If you are installing another camera app like Open Camera, it is working. (Only happens in the emulator)
The location is most certainly saved as meta info in the media store and not in exif header of jpg.
Download jpg to pc and inspect there exif to see.
You can query the media store for the location too. You dont need the location permission but need another special permission then. Well on Android Q.
I have an Android 8 device where the camera app already behaved that way.
Terrible to loose all info when you use the file somewhere else or make a backup.
Regardless of whether I use an emulated camera or use my webcam as the emulated device's camera, I cannot save photos. My code sets up a new file to save the photo, the camera activity pops up, but after I take the picture, hitting the 'save' or 'accept picture' button doesn't do anything. The only way I can return to my app's activity it by hitting cancel. This code works when I run it on my Galaxy S3, but not an emulated Nexus device. When I set up the device in AVD Manager, I always make sure to enable to set both cameras to either emulated or webcam0, whichever I am using, and I make sure to have an SD card (even though I save to internal memory) and internal storage sufficient for photos. In my manifest, I declare android.permission.INTERNET, android.permission.WRITE_EXTERNAL_STORAGE, and android.permission.CAMERA. Any ideas?
Here's my code where I start the camera intent:
private void dispatchTakePictureIntent(int position) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile(position);
} catch (IOException ex) {
Log.v("photo", "photoFile failed.");
}
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
} else {
Log.v("tag", "photoFile was equal to null.");
}
}
}
Found a solution! The emulated camera wasn't returning because I used a bad directory (selected in createImageFile above) for saving the File. I started using the directory returned by Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) and that solved the problem.
I'm currently trying to save images taken from a phone to its gallery, but the code below only works if I choose the stock camera app when the chooser dialog pops up. Whenever I choose another camera app(e.g., the Google camera), the taken picture doesn't get saved any where.
To make things even stranger, sometimes the picture does show up in its designated directory in the gallery, but after 15 mins or so, the same goes for when I use the stock camera app: the picture will get saved in the default camera shots directory, but takes quite a bit to show up in its designated directory, if it shows up there at all.
// Capturing Camera Image will launch camera app request image capture
void captureImage() {
//file uri to store image.
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
// Request camera app to capture image
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
getActivity().startActivityForResult(captureIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
well ,
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
does not work anymore .
you should do something like this :
call Camera Activity :
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
and onActivityResult :
if (data.getData() == null) {
Bitmap bm = (Bitmap)
data.getExtras().get("data");
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss").format(new Date());
File pictureFile = new File(Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
.getAbsolutePath()
+ File.separator + "IMG_" + timeStamp);
try {
FileOutputStream fos = new FileOutputStream(
pictureFile);
bm.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
String filePath = pictureFile.getAbsolutePath();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} } else {
Uri imgUri =data.getData());
}
It turns out my code was working after all. The pictures were being saved in the new directory, but the problem was that the gallery wasn't being updated, which explains why the photos would randomly appear in the directory later on. Being new to this, it never occurred to me that I would have to update the gallery. I only came to this realization after using ES File Explorer to look through my files. To fix my problem, I just made a new method in my CameraFragment that would call on the media scanner. I called this method from onActivityResult().
Here's the new method, though there's nothing really "new" about it since I ran into the same code on other SO questions:
protected void mediaScan() {
getActivity().sendBroadcast(
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse(fileUri.toString())));
}
I also don't need to call the package manager and iterate through the apps that could handle the camera intent if I'm not giving the option to use choose a picture from a gallery, so I'm going to remove all that from my question.
I do not know how to open saved image and display it into gridView.
I make an intent to take a photo:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null && file != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
And file is saved in /data/data/package/files/...
But when I tried to open file and create a bitmap it always return null.
try {
is = this.getContentResolver().openInputStream(Uri.fromFile(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(is);}
even if I use decodeFile method() I still have a null bitmap.
Files exist in data/data/ ... I checked it.
My question is: how can I get dispaly taken image?
Actually you can't store Pictures caught on camera directly on your app memory, you should write it to sdcard and copy it to your space and delete the original. Because camera is a another app that has no privillege to write on your apps storage space. You can check that if you have root permissions.
If you specify your app memory for camera intent it will always return NULL
You can read this for WORLD_WRITEABLE
I would like to capture an image from the camera and save it to the private app cache directory. I realize that I have to give the camera app permission to write to my private directory, so I added the FLAG_GRANT_WRITE_URI_PERMISSION flag.
What's happening is, that the camera app opens, I can take the picture, but when i click on the OK button, nothing happens. The camera app stays open. No log output. I guess it's because of a permission problem.
private void getCameraImage() {
try {
mTmpFile = File.createTempFile("tmp", ".jpg", getCacheDir());
Uri imgUri = Uri.fromFile(mTmpFile);
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// i.setData(imgUri); // if uncommented, i get an ActivityNotFound Exception
startActivityForResult(i, REQUEST_CAMERA);
} catch (IOException e) {
Log.e(TAG, "getCameraImage()", e);
Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show();
}
}
Any insights, on how I could correct that?
Edit:
When I change the directory to the public SD card, then it works fine.
mTmpFile = File.createTempFile("tmp", ".jpg", Environment.getExternalStorageDirectory());
Thanks
Simon
Instead of passing the Uri to store the picture you can use http://developer.android.com/reference/android/hardware/Camera.html#takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
and get the content in your app memory. From there you will be able to do anything you want.
Do not forget that camera applications are using also the gallery and the gallery app is not allowed to check your private directory.