studio programacion móviles desarrollo curso aplicaciones android android-camera

móviles - manual de programacion android pdf



Actividad de la cámara que devuelve null android (10)

Estoy construyendo una aplicación donde quiero capturar una imagen por la actividad de la cámara por defecto y regreso a mi actividad y carga esa imagen en un ImageView. El problema es que la actividad de la cámara siempre devuelve nulo. En mi onActivityResult(int requestCode, int resultCode, Intent data) datos como null . Aquí está mi código:

public class CameraCapture extends Activity { protected boolean _taken = true; File sdImageMainDirectory; Uri outputFileUri; protected static final String PHOTO_TAKEN = "photo_taken"; private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0; @Override public void onCreate(Bundle savedInstanceState) { try { super.onCreate(savedInstanceState); setContentView(R.layout.cameracapturedimage); File root = new File(Environment .getExternalStorageDirectory() + File.separator + "myDir" + File.separator); root.mkdirs(); sdImageMainDirectory = new File(root, "myPicName"); startCameraActivity(); } catch (Exception e) { finish(); Toast.makeText(this, "Error occured. Please try again later.", Toast.LENGTH_SHORT).show(); } } protected void startCameraActivity() { outputFileUri = Uri.fromFile(sdImageMainDirectory); Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE: { if(resultCode==Activity.RESULT_OK) { try{ ImageView imageView=(ImageView)findViewById(R.id.cameraImage); imageView.setImageBitmap((Bitmap) data.getExtras().get("data")); } catch (Exception e) { // TODO: handle exception } } break; } default: break; } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) { _taken = true; } } @Override protected void onSaveInstanceState(Bundle outState) { outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken); } }

¿Estoy haciendo algo mal?


Después de mucha investigación vigorosa, finalmente llegué a una conclusión. Para hacer esto, debe guardar la imagen capturada en el almacenamiento externo. Y luego, recuperar durante la carga. De esta forma, la resolución de la imagen no se degrada y tampoco obtienes NullPointerException. He utilizado la marca de tiempo para nombrar el archivo, así que obtenemos un nombre de archivo único cada vez.

private void fileChooser2() { StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); String pictureName=getPictureName(); fi=pictureName; File imageFile=new File(pictureDirectory,pictureName); Uri pictureUri = Uri.fromFile(imageFile); intent.putExtra(MediaStore.EXTRA_OUTPUT,pictureUri); startActivityForResult(intent,PICK_IMAGE_REQUEST2); }

Función para crear un nombre de archivo:

private String getPictureName() { SimpleDateFormat adf=new SimpleDateFormat("yyyyMMdd_HHmmss"); String timestamp = adf.format(new Date()); return "The New image"+timestamp+".jpg";//give a unique string so that the imagename cant be overlapped with other apps''image formats }

y onActivityResult:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==PICK_IMAGE_REQUEST2 && resultCode==RESULT_OK )//&& data!=null && data.getData()!=null) { final ProgressDialog progressDialog = new ProgressDialog(this); progressDialog.setTitle("Uploading"); progressDialog.show(); Toast.makeText(getApplicationContext(),"2",Toast.LENGTH_SHORT).show(); File picDir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); File imageFile=new File(picDir.getAbsoluteFile(),fi); filePath=Uri.fromFile(imageFile); try { }catch (Exception e) { e.printStackTrace(); } StorageReference riversRef = storageReference.child(mAuth.getCurrentUser().getUid()+"/2"); riversRef.putFile(filePath) .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { progressDialog.dismiss(); Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show(); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { progressDialog.dismiss(); Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show(); } }) .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount(); progressDialog.setMessage("Uploaded " + ((int) progress) + "%..."); } });

Espero que esto ayude :)

Editar: otorgue permisos para la cámara y para escribir y leer desde el almacenamiento en su manifiesto.


Lo estoy haciendo de otra manera. No se garantiza que el campo data.getData () devuelva un Uri, entonces estoy comprobando si es nulo o no, si es así, la imagen está en extras. Entonces el código sería -

if(data.getData()==null){ bitmap = (Bitmap)data.getExtras().get("data"); }else{ bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData()); }

Estoy usando este código en la aplicación de producción, y está funcionando.



Puede generar un mapa de bits desde el archivo que envía a la intención de la cámara. Por favor use este código ...

@Override public void onActivityResult(int requestCode, int resultCode, Intent data){ switch (requestCode) { case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE: { if(resultCode==Activity.RESULT_OK) { int orientation = getOrientationFromExif(sdImageMainDirectory);// get orientation that image taken BitmapFactory.Options options = new BitmapFactory.Options(); InputStream is = null; Matrix m = new Matrix(); m.postRotate(orientation);//rotate image is = new FileInputStream(sdImageMainDirectory); options.inSampleSize = 4 //(original_image_size/4); Bitmap bitmap = BitmapFactory.decodeStream(is,null,options); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true); // set bitmap to image view //bitmap.recycle(); } break; } default: break; } } private int getOrientationFromExif(String imagePath) { int orientation = -1; try { ExifInterface exif = new ExifInterface(imagePath); int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (exifOrientation) { case ExifInterface.ORIENTATION_ROTATE_270: orientation = 270; break; case ExifInterface.ORIENTATION_ROTATE_180: orientation = 180; break; case ExifInterface.ORIENTATION_ROTATE_90: orientation = 90; break; case ExifInterface.ORIENTATION_NORMAL: orientation = 0; break; default: break; } } catch (IOException e) { //Log.e(LOG_TAG, "Unable to get image exif orientation", e); } return orientation; }


Te estás equivocando porque lo estás haciendo mal.

Si pasa el parámetro adicional MediaStore.EXTRA_OUTPUT con la intención de la cámara, la actividad de la cámara escribirá la imagen capturada en esa ruta y no devolverá el mapa de bits en el método onActivityResult .

Si va a verificar la ruta que está pasando, entonces sabrá que en realidad la cámara ha escrito el archivo capturado en esa ruta.

Para más información puede seguir this , this y this


Tuve un problema similar. Comenté algunas líneas en mi archivo de manifiesto que causaron que los datos de las miniaturas se devuelvan como nulos.

Necesita lo siguiente para hacer que esto funcione:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />

Espero que esto resuelva tu problema

Si su teléfono es un Samsung, podría estar relacionado con este http://kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/

Hay otra pregunta abierta que puede brindar información adicional


después de muchas búsquedas:

private static final int TAKE_PHOTO_REQUEST = 1; private ImageView mImageView; String mCurrentPhotoPath; private File photoFile; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_saisir_frais); mImageView = (ImageView) findViewById(R.id.imageViewPhoto); dispatchTakePictureIntent(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == TAKE_PHOTO_REQUEST && resultCode == RESULT_OK) { // set the dimensions of the image int targetW =100; int targetH = 100; // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(photoFile.getAbsolutePath(), 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; // stream = getContentResolver().openInputStream(data.getData()); Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath(),bmOptions); mImageView.setImageBitmap(bitmap); } } 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; } private void dispatchTakePictureIntent() { Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); try { photoFile = createImageFile(); takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST); } catch (IOException e) { e.printStackTrace(); } }


Intenta seguir el código

{ final String[] imageColumns = { MediaStore.Images.Media._ID,MediaStore.Images.Media.DATA }; final String imageOrderBy = MediaStore.Images.Media._ID + " DESC"; Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy); imageCursor.moveToFirst(); do { String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA)); if (fullPath.contains("DCIM")) { //get bitmap from fullpath here. return; } } while (imageCursor.moveToNext());


Si está utilizando un ImageView para mostrar el mapa de bits devuelto por la intención de la cámara, debe guardar la referencia de la vista de imagen dentro de SaveInstanceState y también restaurarla más adelante dentro deRestoreInstanceState. Consulte el código para onSaveInstanceState y onRestoreInstanceState a continuación.

public class MainActivity extends Activity { private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1; String mCurrentPhotoPath; ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); imageView = (ImageView) findViewById(R.id.imageView1); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void startCamera(View v) throws IOException { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File photoFile = null; photoFile = createImageFile(); //intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile)); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); } } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); System.out.println(imageBitmap); imageView.setImageBitmap(imageBitmap); } } private File createImageFile() throws IOException { 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(); System.out.println(mCurrentPhotoPath); return image; } private void setPic() { // Get the dimensions of the View int targetW = imageView.getWidth(); int targetH = imageView.getHeight(); // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(mCurrentPhotoPath, 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(mCurrentPhotoPath, bmOptions); imageView.setImageBitmap(bitmap); } @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); System.out.println(mCurrentPhotoPath); imageView = (ImageView) findViewById(R.id.imageView1); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onRestoreInstanceState(savedInstanceState); System.out.println(mCurrentPhotoPath); imageView = (ImageView) findViewById(R.id.imageView1); } }


File cameraFile = null; public void openChooser() { Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); cameraFile = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg"); takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile)); String pickTitle = "Select or take a new Picture"; // Or get from strings.xml Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,new Intent[]{takePhotoIntent}); startActivityForResult(chooserIntent, SELECT_PHOTO); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case SELECT_PHOTO: if (resultCode == Activity.RESULT_OK) { Uri selectedImage = data.getData(); if (selectedImage != null) { //from gallery } else if (cameraFile != null) { //from camera Uri cameraPictureUri = Uri.fromFile(cameraFile); } } break; } }