Keep Activity "alive" when calling "StartActivityForResult" - android

I have been trying everything to start an Activity for Result but keeping the caller activity seems impossible.
I Have tried setting on the caller activity in the manifest "android:onConfigChanges" for screenSize, orientation and keyboardHidden.
It is very important because in the caller Activity an Asyn Task loads the content from a Web Service.
When the Activity gets resumed after taking the picture, the Caller activity gets destroyed and loads again the entire UI from the Web Service and destroy the user imputs. Is there a way to prevent this?
This is the Caller method for the camera intent.
private void openCamera(){
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
//takePictureIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); <- Commented and not commented with the same problem.
// Create the File where the photo should go
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
An this is the "createImageFile()":
private File createImageFile() throws IOException {
// Create an image file name
File file;
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = timeStamp + "_";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "myAppDirectory");
if (!storageDir.mkdir()){
storageDir.mkdirs();
};
file = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
mCurrentPhotoPath = file.getAbsolutePath();
return file;
}

I have been trying everything to start an Activity for Result but keeping the caller activity seems impossible.
Most likely, your process is being terminated due to low memory conditions. This is fairly typical when using ACTION_IMAGE_CAPTURE or other actions that launch a third-party camera app. It also happens in many other places as well, as your app's process will not live forever.
It is very important because in the caller Activity an Asyn Task loads the content from a Web Service.
Please bear in mind that there are plenty of other cases when your process will be terminated, and you need to be able to deal with this. So, if your concern is re-doing the Web service call, cache the results of the previous call in a file, and only re-issue the call if your cached results are stale. You might also consider whether your activity should be doing this Web service call at all, moving that logic instead into an IntentService.

Related

Android Emulator EXIF Data

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.

Android IMAGE_CAPTURE intent saves photo after onActivityResult

I am trying to take photo using IMAGE_CAPTURE intent and show this photo on the screen immediately. What I do:
File photoFile = createImageFile();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(intent, REQUEST_CAMERA);
Create image file method:
private File createImageFile() {
File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File photoFile = null;
try {
photoFile = File.createTempFile("photo", ".jpg", dir);
mPhotoPath = photoFile.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
return photoFile;
}
When onActivityResult is called I execute:
Bitmap photo = BitmapFactory.decodeFile(mPhotoPath);
mPhoto.setImageBitmap(photo);
Here is a problem. Apparently IMAGE_CAPTURE activity saves image to a file in background and my onActivityResult gets executed before image is saved. Because of this my photo == null. Although it works if I put breakpoint before BitmapFactory.decodeFile call. I fixed it with an ugly hack:
while (photo == null) {
photo = BitmapFactory.decodeFile(mPhotoPath);
}
So, am I doing something wrong? Why it works this way?
I am testing on Marshmallow Nexus 5.
Apparently IMAGE_CAPTURE activity saves image to a file in background and my onActivityResult gets executed before image is saved
I would consider that to be a bug in the specific camera app that is handling your request. There are hundreds, if not thousands, of such camera apps, and bugs like this are somewhat common.
I fixed it with an ugly hack
Busy loops like that are never a good idea. Among other things, it will freeze your UI if done in the main application thread, and it will seriously chew up CPU even if done on a background thread.
I would try a FileObserver to watch for when the file is closed, to be more event-driven. If, for whatever reason, you can't get that to work:
make sure you are doing your watch-for-the-file logic in a background thread
add reasonable SystemClock.sleep() periods between tries (e.g., 50ms)

ImagePath doesn't always work

I'm strugglin with this already all day :-( My current approach looks like this
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/image.jpg");
imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/image.jpg";
startActivityForResult(IntentUtils.dispatchTakePictureIntent(getActivity(), file), REQUEST_IMAGE_CAPTURE);
afterwards i do some unimportant stuff to make display the Bitmap correctly and then display it with this method
placeImageView.setImageBitmap(rotatedBitmap);
*EDIT This is how i create the Intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
if (file != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(file));
return takePictureIntent;
}
}
return null;
}
This works so far.
But when i use this imagePath in the next activity, the bitmap won't load. I already tried before so many things with this file path before, at the moment i just feel owerwhelmed by all the possible ways to handle this ...
This may sound trivial, but you have checked if the image really gets recorded where you want it to be - i.e. have you checked for the image by using the standard phone file explorer? (I would have posted this as a comment, but my reputation is too low.)

Trouble with adding file path to the MediaStore.ACTION_IMAGE_CAPTURE intent

I am adding a photo from the phones camera to a Fragment. I am including the file path to where I would like the pic to get saved in the camera intent(MediaStore.ACTION_IMAGE_CAPTURE).
My problem is that after launching the camera and taking the pic the I am not able to get back to my app. The screen stays in the part where the user gets the option to accept the pic or take another one. The phone doesn't hang or crash and I am able to get back to my app by hitting the back button, but when I get back to the app it is without the pic.
I hope I have made my problem clear, if not let me know and I will try to explain better. I have attached (what I think) are the relevant bits of code.Let me know if you need to see anymore of the code.
Launching the camera intent:
void takePic()
{
if(isExternalStorageWritable() && isExternalStorageReadable())
{
Log.w("Rakshak", "in the take pic");
File file = getPicStoragePath();
Uri uriSavedImage=Uri.fromFile(file);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(intent, CAMERA_IMAGE_ACTIVITY_REQUEST_CODE);
}
}
public File getPicStoragePath() {
Log.w("Rakshak", "in the get pic file");
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + File.separator +"YAN");
if(!dir.exists())
dir.mkdirs();
File file = new File(dir,getPicName());
return file;
}
public String getPicName()
{
Log.w("Rakshak", "in the get pic name");
if(title.getText().toString().trim().length() == 0)
{
Log.w("Rakshak", "no title");
Calendar cal=Calendar.getInstance();//get an instance of the calendar
return String.format("%1$te %1$tB %1$tY,%1$tI:%1$tM:%1$tS %1$Tp",cal);// get the data/time when the note was created
}
else
{
return title.getText().toString().trim();
}
}
I have these permissions in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
The relavent bits from the onActivityResult:
case CAMERA_IMAGE_ACTIVITY_REQUEST_CODE:
Log.w("Rakshak", "in the camera case");
myBitmap = data.getExtras().getParcelable("data");
photo.setVisibility(View.VISIBLE);
photo.setImageBitmap(myBitmap);
update_pic = true;
return;
There are no error messages in the LogCat. And I could not find anything of note in there.
I get the pic inserted onto the image view just fine if I dont add a file path to the camera intent. It is only when I add the file path that the stays in the "accept pic" bit of the camera.
Your getPicStoragePath() might be the issue. Try something like this:
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 = image.getAbsolutePath();
return image;
}

Samsung Galaxy Tab 2 10.1 kills process after taking a picture in camera intent

I noticed very strange behaviour of my device.
I create a new intent with action MediaStore.ACTION_IMAGE_CAPTURE
Then I start an activty for result. But at the moment I take a picture from the camera my application disappears from processes in DDMS perspective. Then in few seconds it is running again.
What is interesting - onActivityResult is called properly and receives an image. But I have some singletones that contain some values in their fields. After process is restarted these singletones are re-initialized and lose all values.
There is no problem on other devices - neither tablets nor phones.
Is it a known bug? Ho to prevent process restarting on Galaxy Tab 2 10.1?
Thanks in advance!
UPDATE: Below is my code that starts camera intent
private void startCameraIntent() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File albumFile;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO){
albumFile = new File (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FOLDER_NAME);
} else {
albumFile = new File(Environment.getExternalStorageDirectory()+CAMERA_DIR+FOLDER_NAME);
}
if (albumFile != null){
if (!albumFile.mkdirs()){
if (!albumFile.exists()){
showToast(getApplicationContext().getString(R.string.sFailedToCreateDirectory));
return;
}
}
}
File imageFile = null;
try {
imageFile = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumFile);
mCurrentPhotoPath = imageFile.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
fileUri = Uri.parse(mCurrentPhotoPath);
startActivityForResult(cameraIntent, ACTION_CAPTURE_IMAGE);
} else {
showToast(getApplicationContext().getString(R.string.sSDNotReady));
}
}
Is it a known bug?
It is not a bug. If your app is not in the foreground, its process can be terminated at any time.
Ho to prevent process restarting on Galaxy Tab 2 10.1?
You can't. Your process can go away at any time when it is not in the foreground. So, for example, if the user presses HOME, and later Android terminates your process, and after that the user tries returning to your app via the recent-tasks list, you will see the same behavior. Your app needs to be able to handle this.
You are welcome to try working with the Camera directly, rather than starting the third-party activity, as that will keep your app in the foreground. This is more complex than what you are doing, though.

Categories

Resources