Intent started in onCreate called multiple times - android

I am making an app that uses the camera and I would like the default camera open as soon as the app is opened. I currently start my image capture intent in the onCreate method of my main activity. This works perfectly fine sometimes, but other times the camera intent is launched 3 consecutive times.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mImageView = (ImageView) findViewById(R.id.imageView1);
mImageBitmap = null;
Button picBtn = (Button) findViewById(R.id.pictureButton);
setBtnListenerOrDisable(
picBtn,
mTakePicOnClickListener,
MediaStore.ACTION_IMAGE_CAPTURE
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
} else {
mAlbumStorageDirFactory = new BaseAlbumDirFactory();
}
dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f;
try {
f = setUpPhotoFile();
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
mCurrentPhotoPath = null;
}
startActivityForResult(takePictureIntent, actionCode);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
handleBigCameraPhoto();
}
}
private void handleBigCameraPhoto() {
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
lastPhotoPath = mCurrentPhotoPath;
mCurrentPhotoPath = null;
}
}
private void setPic() {
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the ImageView */
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW / targetW, photoH / targetH);
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
/* Associate the Bitmap to the ImageView */
mImageView.setImageBitmap(bitmap);
mImageView.setVisibility(View.VISIBLE);
}

I think Nathaniel is giving you good advice to move your camera intent launching into onResume.
However, you'll need to differentiate between an onResume that is your activity starting for the first time from one that is happening because of your activity resuming after the camera intent is finished. If you dont, you'll get the loop you see.
To do this, you can alter your onActivityResult() to set a member variable in your Activity called something like isResumingFromCaptureIntent. Set it to true in onActivityResult when the resultCode matches what you used to start the camera intent. Then, in your onResume, check isResumingFromCaptureIntent, if true you know you dont need to start the camera intent and can set is back to false and proceed with whatever else your activity needs to do.

Look here:
Android: onCreate() getting called multiple times (and not by me)
One piece of guidance I can provide is to try and move that call to
public void onResume(){
}
You'll get the desired behavior of automatically going to the camera, but this might cut down on some of the extra calls, since it only occurs when the activity is actually being shown to the user (including returning from other applications etc..).

In the onCreate method I added logic to check if onCreate had previously been called. I did this by checking if the bundle passed in was null or not
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mImageView = (ImageView) findViewById(R.id.imageView1);
mImageBitmap = null;
Button picBtn = (Button) findViewById(R.id.pictureButton);
setBtnListenerOrDisable(
picBtn,
mTakePicOnClickListener,
MediaStore.ACTION_IMAGE_CAPTURE
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
} else {
mAlbumStorageDirFactory = new BaseAlbumDirFactory();
}
if(savedInstanceState == null)
dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
}

Related

App is crashing after capturing picture using intents

My app is crashing after capturing 5 to 6 photos using intents.log cat shows nothing. am unable to find the reason why it is crashing. please help me out.
private void capturePhoto() {
File root = new File(Environment.getExternalStorageDirectory(), "Feedback");
if (!root.exists()) {
root.mkdirs();
}
File file = new File(root, Constants.PROFILE_IMAGE_NAME + ".jpeg");
Uri outputFileUri = Uri.fromFile(file);
Intent photoPickerIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
photoPickerIntent.putExtra("return-data", true);
photoPickerIntent.putExtra("android.intent.extras.CAMERA_FACING", 1);
startActivityForResult(photoPickerIntent, requestCode);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (this.requestCode == requestCode && resultCode == RESULT_OK) {
File root = new File(Environment.getExternalStorageDirectory(), "Feedback");
if (!root.exists()) {
root.mkdirs();
}
File file = new File(root, Constants.PROFILE_IMAGE_NAME+".jpeg");
checkFlowIdisPresent(file);
displayPic();
}
}
private void displayPic() {
String filePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "/Feedback/" + Constants.PROFILE_IMAGE_NAME + ".jpeg";
// Bitmap bmp = BitmapFactory.decodeFile(filePath);
//Bitmap scaled = Bitmap.createScaledBitmap(bmp, 300, 300, true);
File imgFile = new File(filePath);
Bitmap bmp = decodeFile(imgFile);
if (imgFile.exists()) {
dispProfilePic.setImageBitmap(bmp);
} else {
dispProfilePic.setBackgroundResource(R.drawable.user_image);
}
}
private Bitmap decodeFile(File f) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 70;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}
And above code is for capturing photo and displaying captured picture in ImageView. And am using MI tab.
Edit actually app is not crashing...it becomes white screen and if i press any button then it is crashing and onActivityResult is not executed when it become white screen
New Edit Am able to replicate this. I clicked on Android Monitor in that i clicked Monitor. Then it shows memory utilization of the app when i interacting with app. now in left side bar i clicked terminate application icon. Now the interesting thing is it destroys current activity and moves to previous activity. That previous activity become white screen.
Please help me out guys.
Try this code. I use it in some of my apps :
Launch intent method:
private void launchCamera() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
Capturing result:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == CAMERA_PIC_REQUEST) {
if (data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap thumbnail = (Bitmap) extras.get("data");
if (thumbnail != null)
displayPic(thumbnail);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Well your code fine....
I think you save the image or overwrite image on same path with same name so there is problem with memory. So I recommended you change the name with System.currentTimeMillis() or any random name Instead of Constants.PROFILE_IMAGE_NAME.
And Also check the permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Also check this permission with run time also...for run time follow this
private static final int REQUEST_RUNTIME_PERMISSION = 123;
if (CheckPermission(demo.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
capturePhoto();
} else {
// you do not have permission go request runtime permissions
RequestPermission(demo.this, Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_RUNTIME_PERMISSION);
}
public void RequestPermission(Activity thisActivity, String Permission, int Code) {
if (ContextCompat.checkSelfPermission(thisActivity,
Permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Permission)) {
capturePhoto();
} else {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Permission},
Code);
}
}
}
public boolean CheckPermission(Activity context, String Permission) {
if (ContextCompat.checkSelfPermission(context,
Permission) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
If nothing is displayed on the log cat it is very difficult to speculate anything but please check whether the problem is when using the emulator and not on a real device. You can also check if you can recreate the problem by making the emulator capacity smaller (Ram and internal memory). If that is the case, then increase the memory or ram of your emulator and it should work fine. You then need to work on optimizing you image processing task for lower spec devices.
Hope this helps.
This happens possibly because the Calling Activity gets killed and then restarted by OS as IMAGE CAPTURE intent deals with huge amount of memory for processing the BITMAP captured via CAMERA.
Solution: Save the file path of the Image and use it when onActivityResult is called. You can use onSavedInstanceState and onRestoreInstanceState methods to save and retrieve the IMAGE_PATH and other fields of the activity.
You can refer to this link for how to use onSavedInstanceState and onRestoreInstanceState
Try doing it in an Async task because the issue u facing is due to the hug processing done in UI thread
refer here for more help on Async task implementation
This may be memory problem you are taking photos and storing them in bitmap
Check your android Monitor for Memory Detection of APp
Just make this method static
private static Bitmap decodeFile(File f) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 70;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}
Save files with different names like saving with timestamp as name
Try to use below code. It works fine for me.
private static final int REQUEST_CAMERA = 1;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
if (requestCode == REQUEST_CAMERA)
{
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");
FileOutputStream fos;
try
{
destination.createNewFile();
fos = new FileOutputStream(destination);
fos.write(bytes.toByteArray());
fos.close();
}
catch (FileNotFoundException fnfe)
{
fnfe.printStackTrace();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
ivSetImage.setImageBitmap(thumbnail);
}
}
}
In the given code snippet, I have compressed the captured image, due to which app crashing problem is resolved.
In your case, the captured image quality might be high due to which your app is crashing while setting up an image on ImageView.
Just try compressing an image. It will work!
Don't forget to add permission in manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
check your Manifast.xml file permission
External Storage
and Camera permission.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" /> <uses-feature
android:name="android.hardware.camera.autofocus" />
if your App run on Marshenter code heremallow check run time permission
Try to use below code:
private void launchCamera() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == CAMERA_PIC_REQUEST) {
if (data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap thumbnail = (Bitmap) extras.get("data");
if (thumbnail != null)
displayPic(thumbnail);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

Set the dimensions of image captured in android

In my application, I have an activity where we can capture the image from camera on button click using intent and set the captured image into imageview. Its working absolutely fine.
But now i want the image in specific dimensions. For example, in my case the dimensions of my image view is 150dp * 150dp. So i want that the dimensions of image captured by camera should also always be 150dp * 150dp in order to fit perfectly. How can i do this?
Here's my main activity.
public class MainActivity extends Activity implements OnClickListener {
Button btnTackPic;
TextView tvHasCamera, tvHasCameraApp;
ImageView ivThumbnailPhoto;
Bitmap bitMap;
static int TAKE_PICTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get reference to views
tvHasCamera = (TextView) findViewById(R.id.tvHasCamera);
tvHasCameraApp = (TextView) findViewById(R.id.tvHasCameraApp);
btnTackPic = (Button) findViewById(R.id.btnTakePic);
ivThumbnailPhoto = (ImageView) findViewById(R.id.ivThumbnailPhoto);
// Does your device have a camera?
if(hasCamera()){
tvHasCamera.setBackgroundColor(0xFF00CC00);
tvHasCamera.setText("You have Camera");
}
// Do you have Camera Apps?
if(hasDefualtCameraApp(MediaStore.ACTION_IMAGE_CAPTURE)){
tvHasCameraApp.setBackgroundColor(0xFF00CC00);
tvHasCameraApp.setText("You have Camera Apps");
}
// add onclick listener to the button
btnTackPic.setOnClickListener(this);
}
// on button "btnTackPic" is clicked
#Override
public void onClick(View view) {
// create intent with ACTION_IMAGE_CAPTURE action
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Edit to save picture
File file = new File(Environment.getExternalStorageDirectory(), "my-photo.jpg");
Uri photoPath = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoPath);
// start camera activity
startActivityForResult(intent, TAKE_PICTURE);
}
// The Android Camera application encodes the photo in the return Intent delivered to onActivityResult()
// as a small Bitmap in the extras, under the key "data"
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == TAKE_PICTURE && resultCode== RESULT_OK && intent != null){
// get bundle
Bundle extras = intent.getExtras();
// get
bitMap = (Bitmap) extras.get("data");
ivThumbnailPhoto.setImageBitmap(bitMap);
}
}
// method to check you have a Camera
private boolean hasCamera(){
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
// method to check you have Camera Apps
private boolean hasDefualtCameraApp(String action){
final PackageManager packageManager = getPackageManager();
final Intent intent = new Intent(action);
List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
}
Thanks in advance.
You need to scale your Bitmap like the following code:
Bitmap originalBitmap = <the original bitmap>;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
originalBitmap, newWidth, newHeight, false);
Hence according to your requirement,the resized bitmap must be generated as:
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
bitMap, 150,150, false);
Note:Here 150 is measured in pixels,so you have to calculate 150dp to pixel and then place it.

Android - Take a picture not working

I'm trying to make a simple app:
I made a button, its onClick should call the camera intent, save the picture in the internal storage and then i want to put the picture in a custom listview gallery... for now I haven't made the listview because I'm having problems with the intent. the camera doesn't open and I don't know why even if the right permissions are in the manifest file
any help is appreciated, I've tried a lot of tutorials but I can't find the problem.
public class MainActivity extends Activity implements View.OnClickListener {
public static final String LOG_TAG = "LOG_TAG" ;
public static final int CAMERA_REQUEST = 1; /* ci serve la richiesta per la camera*/
private Button btCamera;
private Button btSavePicture;
private ImageView imageViewShowPicture;
private File imageFile;
/*attributi per salvare foto*/
private String savePicturePath;
/*_____________________________________________________________________________________________oncreate*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*Collego oggetti alla grafica*/
btCamera = (Button)this.findViewById(R.id.btCamera);
btSavePicture = (Button) this.findViewById(R.id.btSalvaFoto);
this.imageViewShowPicture = (ImageView) this.findViewById(R.id.ivMostraFoto);
/*listener*/
btCamera.setOnClickListener(this);
btSavePicture.setOnClickListener(this);
}
/*___________________________________________________________________________________________metodo TAKE A PHOTO*/
private void startTakeAPictureIntent(){
Intent takeAPictureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.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
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, CAMERA_REQUEST);
}
}}
/*___________________________________________________________________________________________metodo crea image file*/
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
savePicturePath = "file:" + image.getAbsolutePath();
return image;
}
/*______________________________________________________________________________________metodo aggiungi alla gallery*/
private void addPicToGallery() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(savePicturePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
/*______________________________________________________________________________________metodo decodificare un'immagine scalata*/
private void setPic() {
// Get the dimensions of the View
int targetW = imageViewShowPicture.getWidth();
int targetH = imageViewShowPicture.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(savePicturePath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(savePicturePath, bmOptions);
imageViewShowPicture.setImageBitmap(bitmap);
}
/*_____________________________________________________________________________________________onclick*/
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btCamera: {
Log.d(LOG_TAG, "Ho premuto btcamera");
Toast.makeText(MainActivity.this, "Camera clicked", Toast.LENGTH_SHORT).show();
startTakeAPictureIntent();
/*Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, RICHIESTA_FOTOCAMERA);*/
} break;
case R.id.btSalvaFoto:{
Log.d(LOG_TAG, "Ho premuto btsalvafoto");
Toast.makeText(MainActivity.this, "salvafoto clicked", Toast.LENGTH_SHORT).show();
}
}
}
/*_____________________________________________________________________________________________onActivity result*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) { /* se la richiesta mi da risultati*/
Bundle extras = data.getExtras();
Bitmap immagineBitmap = (Bitmap)extras.get("data"); /* prendi gli extra */
imageViewShowPicture.setImageBitmap(immagineBitmap); /*setto la imageview per mostrarla*/
}
}
}// chiude activity
Please try to add following permission and see.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Please refer to https://developer.android.com/guide/topics/media/camera.html#manifest to see anything other you need to declare.

android bitmap from camera is just thumbnail size?

i am making an app of which it can initialize the camera and then after taking the photo, the photo could be imported and the user to further draw on it.
Coding:
Class A:
public OnClickListener cameraButtonListener = new OnClickListener()
{
#Override
public void onClick(View v)
{
vibrate();
Toast.makeText(Doodlz.this, R.string.message_initalize_camera, Toast.LENGTH_SHORT).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
};
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK)
{
Bitmap photo = (Bitmap) data.getExtras().get("data");
Bitmap photocopy = photo.copy(Bitmap.Config.ARGB_8888, true);
doodleView.get_camera_pic(photocopy);
}
}
doodleView:
public void get_camera_pic (Bitmap photocopy)
{
// get screen dimension first
WindowManager wm = (WindowManager) context_new.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
final int screenWidth = display.getWidth();
final int screenHeight = display.getHeight();
bitmap = photocopy;
bitmap = Bitmap.createScaledBitmap(bitmap, screenWidth, screenHeight, true);
bitmapCanvas = new Canvas(bitmap);
invalidate(); // refresh the screen
}
Question:
The photo can be successfully captured using the camera and return to doodleView for user. Yet since the imported image dimension is very small, just a thumbnail size!! (dont know why), so I tired scaling it up and then the resolution is very poor.
My question is that, how modify the above code so as to set the photo taken dimension be fitting to the screen's dimension and the returned photo be 1:1 of the screen instead of getting like a thumbnail one? (best to be fit 1:1 of screen, because if it is then importing as original photo size the photo dimension is then greater then the screen, it then need to scale down and distorted by different ratio of width and height ratio to fit full screen)
Thanks!!
This is normal for the default camera application. The way to get the full size image is to tell the camera activity to put the result into a file. First create a file and then start the camera application as follows:
outputFileName = createImageFile(".tmp");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputFileName));
startActivityForResult(takePictureIntent, takePhotoActionCode);
Then in your onActivityResult, you can get this image file back and manipulate it.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == takePhotoActionCode)
{
if (resultCode == RESULT_OK)
{
// NOTE: The intent returned might be NULL if the default camera app was used.
// This is because the image returned is in the file that was passed to the intent.
processPhoto(data);
}
}
}
processPhoto will look a bit like this:
protected void processPhoto(Intent i)
{
int imageExifOrientation = 0;
// Samsung Galaxy Note 2 and S III doesn't return the image in the correct orientation, therefore rotate it based on the data held in the exif.
try
{
ExifInterface exif;
exif = new ExifInterface(outputFileName.getAbsolutePath());
imageExifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
}
catch (IOException e1)
{
e1.printStackTrace();
}
int rotationAmount = 0;
if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_270)
{
// Need to do some rotating here...
rotationAmount = 270;
}
if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_90)
{
// Need to do some rotating here...
rotationAmount = 90;
}
if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_180)
{
// Need to do some rotating here...
rotationAmount = 180;
}
int targetW = 240;
int targetH = 320;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(outputFileName.getAbsolutePath(), bmOptions);
int photoWidth = bmOptions.outWidth;
int photoHeight = bmOptions.outHeight;
int scaleFactor = Math.min(photoWidth/targetW, photoHeight/targetH);
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap scaledDownBitmap = BitmapFactory.decodeFile(outputFileName.getAbsolutePath(), bmOptions);
if (rotationAmount != 0)
{
Matrix mat = new Matrix();
mat.postRotate(rotationAmount);
scaledDownBitmap = Bitmap.createBitmap(scaledDownBitmap, 0, 0, scaledDownBitmap.getWidth(), scaledDownBitmap.getHeight(), mat, true);
}
ImageView iv2 = (ImageView) findViewById(R.id.photoImageView);
iv2.setImageBitmap(scaledDownBitmap);
FileOutputStream outFileStream = null;
try
{
mLastTakenImageAsJPEGFile = createImageFile(".jpg");
outFileStream = new FileOutputStream(mLastTakenImageAsJPEGFile);
scaledDownBitmap.compress(Bitmap.CompressFormat.JPEG, 75, outFileStream);
}
catch (Exception e)
{
e.printStackTrace();
}
}
One thing to note is that on Nexus devices the calling activity is not normally destroyed. However on Samsung Galaxy S III and Note 2 devices the calling activity is destroyed. Therefore the just storing the outputFileName as a member variable in the Activity will result in it being null when the camera app returns unless you remember to save it when the activity dies. It's good practice to do that anyhow, but this is a mistake that I've made before so I thought I'd mention it.
EDIT:
Regarding your comment, the createImageFile is a not in the standard API, it's something I wrote (or I may have borrowed :-), I don't remember), here is the method for createImageFile():
private File createImageFile(String fileExtensionToUse) throws IOException
{
File storageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
),
"MyImages"
);
if(!storageDir.exists())
{
if (!storageDir.mkdir())
{
Log.d(TAG,"was not able to create it");
}
}
if (!storageDir.isDirectory())
{
Log.d(TAG,"Don't think there is a dir there.");
}
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "FOO_" + timeStamp + "_image";
File image = File.createTempFile(
imageFileName,
fileExtensionToUse,
storageDir
);
return image;
}
To access the full image, you either need to access the intent URI by using data.getData() in your doodleView, or (better) provide your own URI for storing the image by passing it to the intent by supplying a URI in EXTRA_OUTPUT extra.

Android: wrong orientation of files opened with BitmapFactory.decodeFile

Just simple as the title, files opened with BitmapFactory.decodeFile have wrong orientation when it is displayed on the ImageView. The image its captured from the camera and saved on a tmp file so if the device has the bug that returns data.getData() null I have at least a reference to the file.
This just start the camera activity and capture the image file
private void startCamera() {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Constants.TMPFILE_PATH)));
} else {
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST) {
if (resultCode == RESULT_OK) {
Uri uri = null;
if (hasImageCaptureBug()) {
File f = new File(Constants.TMPFILE_PATH);
try {
uri = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), null, null));
} catch (FileNotFoundException e) {
}
} else {
uri = data.getData();
}
imageFilePath = Image.getPath(this, uri);
if (Image.exists(imageFilePath)) {
ImageView image = (ImageView) findViewById(R.id.thumbnail);
int targetW = (int) getResources().getDimension(R.dimen.thumbnail_screen_width);
int degrees = (int) Image.getRotation(this, uri);
Bitmap bmp = Image.resize(imageFilePath, targetW);
bmp = Image.rotate(bmp, degrees);
image.setAdjustViewBounds(true);
image.setImageBitmap(bmp);
}
}
}
}
And this file resizes the image
public class Image {
public static Bitmap resize(String pathName, int targetW) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(pathName, opts);
int photoW = opts.outWidth;
int photoH = opts.outHeight;
int targetH = Math.round((photoH * targetW) / photoW);
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
opts.inJustDecodeBounds = false;
opts.inSampleSize = scaleFactor;
opts.inPurgeable = true;
bmp = BitmapFactory.decodeFile(pathName, opts);
return bmp;
}
}
Tryed to get the ExifOrientation but always its 0 because the file itself its correctly oriented just when I load it the file is displayed with the wrong orientation.
Regards
seems that my issue to preview the image was the Constants.TMPFILE_PATH, the image was not saved there, I just use this fix Display the latest picture taken in the image view layout in android!, but the issue persist if I post it to the server... I'll check this as answered and open a new question to this...
Edited
To solve this issue just refactor the new image and then upload it to the server, because the raw data of the file itself has his exif orientation was wrong.

Categories

Resources