Development Tip

null android를 반환하는 카메라 활동

yourdevel 2020. 12. 3. 20:41
반응형

null android를 반환하는 카메라 활동


기본 카메라 활동으로 이미지를 캡처하고 내 활동으로 돌아가서 해당 이미지를 ImageView에로드하려는 애플리케이션을 빌드 중입니다. 문제는 카메라 활동이 항상 null을 반환한다는 것입니다. onActivityResult(int requestCode, int resultCode, Intent data)방법에서 나는 데이터를 null. 내 코드는 다음과 같습니다.

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);
    }
}

내가 뭘 잘못하고 있니?


당신은 잘못하고 있기 때문에 잘못되고 있습니다.

MediaStore.EXTRA_OUTPUT카메라 인 텐트와 함께 추가 매개 변수를 전달하면 카메라 활동이 캡처 된 이미지를 해당 경로에 쓰고 onActivityResult메서드 에서 비트 맵을 반환하지 않습니다 .

통과하는 경로를 확인하면 실제로 카메라가 해당 경로에 캡처 된 파일을 기록했음을 알 수 있습니다.

자세한 내용은 , thisthis


다른 방식으로하고 있습니다. data.getData () 필드는 Uri를 반환한다고 보장되지 않으므로 null인지 아닌지 확인하고 있습니다. 그렇다면 이미지가 엑스트라에 있습니다. 그래서 코드는-

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

프로덕션 응용 프로그램에서이 코드를 사용하고 있으며 작동 중입니다.


비슷한 문제가있었습니다. 내 매니페스트 파일의 일부 줄을 주석 처리하여 축소판 데이터가 null로 반환되었습니다.

이 작업을 수행하려면 다음이 필요합니다.

<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" />

문제가 해결되기를 바랍니다.

휴대 전화가 삼성이라면 http://kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/ 과 관련이있을 수 있습니다.

추가 정보를 제공 할 수있는 또 다른 미해결 질문 이 있습니다.


ImageView를 사용하여 Camera Intent에서 반환 된 비트 맵을 표시하는 경우 onSaveInstanceState 내에 imageview 참조를 저장하고 나중에 onRestoreInstanceState 내에서 복원해야합니다. 아래의 onSaveInstanceState 및 onRestoreInstanceState에 대한 코드를 확인하십시오.

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);
    }
}

많은 검색 후 :

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();
    }
}

다음 코드를 시도하십시오

            {
                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());

카메라 인 텐트로 보내는 파일에서 비트 맵을 생성 할 수 있습니다. 이 코드를 사용하십시오 ...

@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;
    }

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;
    }
}

이 튜토리얼을 시도해보십시오. 그것은 나를 위해 작동하고 선언문에서 평소와 같이 권한을 사용하고 권한도 확인합니다.

https://androidkennel.org/android-camera-access-tutorial/


After a lot of vigorous research I finally reached to a conclusion. For doing this, you should save the image captured to the external storage. And then,retrieve while uploading. This way the image res doesnt degrade and you dont get NullPointerException too! I have used timestamp to name the file so we get a unique filename everytime.

 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);
}

Function to create a file name :

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
}

and the 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) + "%...");
                        }
                    });

Hope this helps :)

Edit: give permissions for camera and to write and read from storage in your manifest.

참고URL : https://stackoverflow.com/questions/6982184/camera-activity-returning-null-android

반응형