i am trying to open the camera and set a path to which the camera picture should be saved as shown in the following line:
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(this.mFileImgPath))
the problem i have is, if i took the picture while the camera in the portrait mode then 'onActivityResult' will be called normally and when i check 'mFileImgPath' it wil be not null. But when i use the same code and take a picture
in the landscape mode, then 'onActivityResult' will be called but always 'mFileImgPath' is null.
to invstigate further, i used the debugger and 'mFileImgPath' is always null if i tried to take a picture in the Lanscape mode. pleae have a look at the screen shot of the debugger
please let me know why the 'mFileImgPath' is always null in landscape mode? and how to olve it
code
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
this.mFileImgPath = new File(App.instance.getOutDir() + "/" + new Date().getTime());
Log.e(TAG, "mFileImgPath" + mFileImgPath);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(this.mFileImgPath));
debugger
as shown in the screen shot, the 'mFileImgPath' is null and when i click steo over the debugger skips the if-condition
This is known issue when working with inbuilt camera. In order to fix this you have to retain the uri via onSaveInstanceState() and onRestoreInstanceState().
Before your declare the startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE) , declare intent.putExtra(..) so:
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
Now put these 2 methods in your activity
/* Storing the file url as it'll be null after returning from camera app */
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on scren orientation changes
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
Do not try to access Intent in onActivityResult(int requestCode, int resultCode, Intent data) , the parameter data is most likely going to be null.
Your activity can be killed when the camera app is up. Activities not on fore ground can at any time be killed by Android.
You should #overide onSaveInstanceState and save the value of the path variable there. Then retrieve the value in onRestoreInstanceState.
Related
What should be happening:
A user clicks on a button which brings up their phone's image gallery. They select an image via startActivityForResult, which I then get the path for and handle it from there.
What is happening:
When I click the button, the gallery opens up perfectly. But when I select an image, onActivityResult is never called and instead of closing the gallery and going back to the initial activity, the app goes back to the activity before it. Like it's calling onBackPressed or something.
My code for opening the gallery:
profilePicView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 1);
}
}
Trying to get the result (this never gets called):
public void onActivityResult(int requestCode, int resultCode, Intent data){
// none of this is every called, including the entire onActivityResult method
if(requestCode == 1){
Uri selectedImageUri = data.getData();
selectedProfilePicPath = getPath(selectedImageUri);
}
}
So all I'm trying to do is get the path to the selected image with onActivityResult. But that is never being called and for some reason this action causes the activity to go back to the previous activity. If it matters, this is an Activity and not a Fragment.
Thanks
The issue was that I had "noHistory=true" defined in the Android Manifest for this Activity. Removing that fixed everything.
My application is a portrait locked application. The application structure is based on one activity and multiple fragments. I am using support v4 fragments for this and fragments has nesting also. While I am trying to take pictures from the camera, for my profile update fragment. The camera app is open and I can capture and save the image. the image is getting in the onActivityResult() successfully.
But randomly the application orientation is getting distorted and its automatically change to landscape.Because of that, the current fragment state is missing. I locked the orientation from Manifest file as android: screenOrientation="portrait for my activity. This issue is mainly getting in Custom android phone (Samsung, HTC etc). I required a directional guideline, whether I need to create a custom camera or any alternate fix for this issue.
My Camera call method from my fragment is given below:
private void callCamera() {
try {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}catch (Exception e){
e.printStackTrace();
}
}
And I am getting the result in onActivityResult() of my Fragment as like this
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if( requestCode == CAMERA_REQUEST && resultCode == mActivity.RESULT_OK){
/**
* For Default Camera callback
*
*/
Bitmap image = (Bitmap) data.getExtras().get("data");
if(image != null){
AppUtility.mCapturedImage = image;
mIvProfileImg.setImageBitmap(image);
}
}
}
Simple solution will be handle it in onSaveInstanceState method.you cannot control camera intent rotation.setting your rotation to portrait and take picture in landscape mode it rotates your activity forcefully it loses its state.
I have the next problem:
when I try to start my camera, I can take the picture, even save it on my sdcard, but when I'm going to get the path for showing it on my device I get errors.
My global variables are 2 (I used 1 but 2 are better for making sure it's a strange error):
private File photofile;
private Uri mMakePhotoUri;
and this is my start-camera function:
#SuppressLint("SimpleDateFormat")
public void farefoto(int num){
// For naming the picture
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String n = sdf.format(new Date());
String fotoname = "Immagine-"+ n +".jpg";
//Going through files and folders
File photostorage = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File photostorage2 = new File(photostorage, "Immagini");
System.out.println(photostorage+"\n"+photostorage2);
photostorage2.mkdirs();
// My file (global)
photofile = new File(photostorage2, fotoname);
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //intent to start camera
// My URI (global)
mMakePhotoUri = Uri.fromFile(photofile);
new Bundle(); // I took this code from internet, but if I remove this line, it's the same
i.putExtra(MediaStore.EXTRA_OUTPUT, mMakePhotoUri);
startActivityForResult(i, num); //num would be 1 on calling function
}
and my activityresult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == 1){
try{ // tring my global URI
photo = f.decodeAndResizeFile(new File(mMakePhotoUri.getPath()));
}
catch(NullPointerException ex){
System.out.println("fail");
ex.printStackTrace();
try{ // Trying my global FILE
photo = BitmapFactory.decodeFile(photofile.getAbsolutePath());
} catch (Exception e){
e.printStackTrace();
Toast.makeText(this, "C'รจ stato un errore. Riprova a scattare la foto.", Toast.LENGTH_LONG).show();
}
......
......
.......
}
Always getting NullPointerException
But... if I take the picture again, IT WORKS!!.
I've read everything I could here... but it doesn't have logic when I modify a global variable and I cannot take it again...
Thanks in advance.
Cheers.
SOLUTION
As Alex Cohn said, my problem was that I was calling onCreate before onActivityResult because of a probably push out of memory (because sometimes doesn't do it), so I wanted to have my app "healthy" and I tried some try / catch and so I get the data even if it's calling onCreate or onActivityResult for the first call, and I wrote that data in a Bundle like explained in the link of restoring our state.
Thanks!.
It's possible that launching of ACTION_IMAGE_CAPTURE will push your activity out of memory. You should check (I'd simply a log, debugger may have its own side effects) that onCreate() of your activity is called before onActivityResult(). If this is the case, you should prepare your activity to reinitialize itself, probably using onSaveInstanceState(Bundle).
Note that the decision whether to shut down the activity, or keep it in background, depends on the overall system state that is beyond your control. It won't surprise me if the decision when you take the first picture, is "shut him down!", but when you take picture again, it is "keep him in background".
It doesnot destroy the variables. But after So many days of research LOL I have got a solution of my mistake.
When I put the debugger the method calls it like after taking a picture.
onCreate()
onActivityResult()
onCeate()
onResume()
Its fixed by just put these following lines in t the menifest. It happens due to camera config changes & window soft input mode.
<activity
android:name="packageName.Activity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" >
I am trying to use the built-in camera application to take a photo and view it through an ImageView.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
addButtonListeners();
startCamera();
}
private void startCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, PHOTO_TAKEN);
}
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == PHOTO_TAKEN) {
Bundle extras = intent.getExtras();
photo = (Bitmap) extras.get("data");
if (photo != null) {
ImageView image = (ImageView) findViewById(R.id.image_background);
image.setImageBitmap(photo);
} else {
Toast.makeText(this, R.string.unable_to_read_photo, Toast.LENGTH_LONG)
.show();
}
}
}
When holding the phone in portrait position this code works just fine, however when I take the picture in landscape it breaks, any ideas why or how to solve this?
Question in not defined with enough details to answer it for sure, but my guess would be the same as Shani Goriwal .
It looks like problems with configuration changes event - which happens each time orientation is changed (from landscape to portrait).
Try to add to AndroidManifest of your app following lines:
android:configChanges="orientation|screenSize"
(more details: http://developer.android.com/guide/topics/resources/runtime-changes.html)
I found a tutorial that explains how to appropriately use the in built camera. Here is the link.
I am relativly new on android but from what I have read is the every time the display rotates android creates a new instance of some sort. So you have to save the instance of the rotation and this is done with the following code:
/**
* Here we store the file url as it will be null after returning from camera
* app
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on scren orientation
// changes
outState.putParcelable("file_uri", fileUri);
}
/*
* Here we restore the fileUri again
*/
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
If you click on the link you should go to bullet number 11. Avoiding NullPointerException after taking camera picture. The real hero here is Ravi Tamada who does an excellent tutorial on using the camera. I recommend reading the whole tutorial.
Again I am new at this so if there is any corrections on what I have wrote here please correct.
I'm trying to get a picture from user and then send it to our server. I provide two options: choosing from gallery or taking a new picture using default camera in their phones.
Gallery thing works correctly, I can get the photo they selected and send it without any problem. But in camera option, camera opens, takes a picture, saves it on SD card with the location I specified, no problem, but when it returns back to my application, I always get a NullPointerException and my application is forced to close. Here is what I do:
private String tempFilePath = "";
...
public void addPhotoUsingCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
tempFilePath = getOutputMediaFilePath(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(tempFilePath)));
startActivityForResult(intent, CAMERA_ACTIVITY_CODE);
}
And then I use following to get the photo taken:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
...
case CAMERA_ACTIVITY_CODE:
if (resultCode == Activity.RESULT_OK) {
picture = new File(tempFilePath);
}
break;
...
}
}
I also tried
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ImageView image = (ImageView) findViewById(R.id.photoTaken);
image.setImageBitmap(thumbnail);
inside case CAMERA_ACTIVITY_CODE: but no matter what I try I always get a NullPointerException in this part of code.
There is the logcat info where line 202 corresponds to case CAMERA_ACTIVITY_CODE: part.
01-31 23:40:13.154: ERROR/AndroidRuntime(8009): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=101, result=-1, data=null} to activity {com.ollaa.android/com.ollaa.android.share.ShareFinalScreen}: java.lang.NullPointerException
01-31 23:40:13.154: ERROR/AndroidRuntime(8009): Caused by: java.lang.NullPointerException
01-31 23:40:13.154: ERROR/AndroidRuntime(8009): at com.ollaa.android.share.ShareFinalScreen.onActivityResult(ShareFinalScreen.java:202)
Any help is greatly appreciated.
Note: I have declared all necessary permissions in AndroidManifest related to camera and SD card.
EDIT: I realized that tempFilePath does not last until camera activity returns to my app. I put the initialization for tempFilePath in my onCreate method but this time picture is not set when I try to reach it from an outside function other than onActivityResult. I feel like I do not know Java at all, when we change a class variable within a function, the changed value should be visible from all functions of that class right??
When using:
intent.putExtra(MediaStore.EXTRA_OUTPUT, myFile);
The file must exist on the 'disk'. The Camera Activity does not create it, which is IMHO a bug. So you have to use myFile.createNewFile();
Also, You have to send Camera Activity a file and not a path.
Try something like this:
tempFilePath = getOutputMediaFilePath(MEDIA_TYPE_IMAGE);
String fileName = "myPhoto";
File myFile = new File (tempFilePath,fileName);
myFile.createNewFile();
// at this point stop the debugger and check if the file exists on the 'disk'.
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(myFile)));
There may be a better way to do this without using MediaStore.EXTRA_OUTPUT. Maybe another user can help.
Also, note if the user presses cancel and does not take a picture you have to delete the file.
Note: I am using Android API 2.2.
I hope this helps.