Android Emulator EXIF Data - android

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.

Related

In Android, How to get image without saving image file

thank you for your appreciation in advance.
I am coding in next contidion.
a. use internal camera app(I use Intent and other app to take pickture).
b. get image without saving into file.
In my app, user take pickture of a credit card and send to server. Credit card image file is not necessary and saving image into file is not good for security.
Is it possible?
If it is impossible, is there anything else?
a. opening jpg file, editing all pixel into black
b. use https://github.com/Morxander/ZeroFill
Whitch method is properable?
Short answer is NO.
You can't get an photo from default camera app without saving it into image.
What you can do is use Camera API to take photo inside your app, not using 3rd party default system photo app.
Look here full Source.
Request this permission on the AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
On your Activity, start by defining this:
static final int REQUEST_IMAGE_CAPTURE = 1;
private Bitmap mImageBitmap;
private String mCurrentPhotoPath;
private ImageView mImageView;
Then fire this Intent in an onClick:
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.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
Log.i(TAG, "IOException");
}
// Continue only if the File was successfully created
if (photoFile != null) {
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
}
}
Add the following support method:
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 = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, // prefix
".jpg", // suffix
storageDir // directory
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
Then receive the result:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath));
mImageView.setImageBitmap(mImageBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
What made it work is the MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath)), which is different from the code from developer.android.com. The original code gave me a FileNotFoundException.

Android Studio emulator camera cannot save photos

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.

Action ACTION_IMAGE_CAPTURE shows package names instead of AppNames

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.

Images not being saved when picture is taken by camera app that isn't the stock camera

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.

Android Camera no save in specific folder [MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA]

I'm a problem when I using the MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA in the Intent. The camera starts correctly but it doesn't save the files in my specific folder "/photo". But when I use the MediaStore.ACTION_IMAGE_CAPTURE it works fine, but I can't use this because it take only one photo each time.
I need the camera starts and the user takes many photos. After he closes the camera and all photos are saved in my specific folder.
Thanks for your help.
Regards,
Marcelo
Source code:
public void startCamera() {
Intent takePictureIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
File file = null;
try {
file = createImageFile();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
} catch (IOException e) {
file = null;
Log.e(this.getClass().getName(), e.getMessage(), e);
}
activity.startActivity(takePictureIntent);
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + JPEG_FILE_SUFFIX;
return new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/photo/", imageFileName);
}
MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA This intent does not support activity results or specific intent file outputs. This intent is designed to simply open the camera. The functionality you seek does not exist natively in Android.

Categories

Resources