Android вылетает после намерения камеры - PullRequest
22 голосов
/ 25 января 2012

У меня опубликовано приложение, и одна из основных функций - позволить пользователю сделать снимок, а затем сохранить его в определенной папке на внешнем хранилище.

Кажется, все работает нормально, но теперь я получил два отчета, в которых утверждается, что после съемки фотографии и нажатия кнопки «Готово», чтобы выйти из камеры (и вернуться в действие), приложениеПринудительно закрыто, возвращая пользователя на главный экран.

Это происходит на Samsung Nexus S и Galaxy Tab.Ниже я разместил свой код, чтобы показать, что я настроил свое намерение и как я сохраняю и отображаю фотографию в onActivityResult ().Будем весьма благодарны за любые рекомендации относительно того, что может вызвать его падение после нажатия кнопки «Готово» для выхода из приложения камеры.

Опять же, это работает нормально на большинстве устройств, но мне было интересно, является ли их более эффективным, универсальным подходом, который я должен использоватьСпасибо

Как я запускаю Намерение камеры

   case ACTION_BAR_CAMERA:

        // numbered image name
        fileName = "image_" + String.valueOf(numImages) + ".jpg";


        output = new File(direct + File.separator + fileName); // create
                                                                    // output
        while (output.exists()) { // while the file exists
            numImages++; // increment number of images
            fileName = "image_" + String.valueOf(numImages) + ".jpg";
            output = new File(outputFolder, fileName);


        }
        camera = new   Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        uriSavedImage = Uri.fromFile(output); // get Uri of the output
        camera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); //pass in Uri to camera intent
        startActivityForResult(camera, 1);


        break;
    default:
        return super.onHandleActionBarItemClick(item, position);
    }
    return true;
}

Как я настраиваю onActivityResult ()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK) { // If data was passed successfully

        Bundle extras = data.getExtras();

        //Bundle extras = data.getBundleExtra(MediaStore.EXTRA_OUTPUT);

        /*ad = new AlertDialog.Builder(this).create();
        ad.setIcon(android.R.drawable.ic_menu_camera);
        ad.setTitle("Save Image");
        ad.setMessage("Save This Image To Album?");
        ad.setButton("Ok", this);

        ad.show();*/



        bmp = (Bitmap) extras.get("data"); // Set the bitmap to the bundle
                                            // of data that was just
                                            // received
        image.setImageBitmap(bmp); // Set imageview to image that was
                                    // captured
        image.setScaleType(ScaleType.FIT_XY);


    }

}

Ответы [ 8 ]

36 голосов
/ 05 июля 2012

Сначала давайте проясним это - у нас есть два варианта получения данных изображения в onActivityResult с камеры:

1. Запустите камеру, передав точное местоположение Uri изображения, в котором вы хотите сохранить.

2. Просто запустите камеру, не передавайте URI Loaction.

<Ч />

1. В ПЕРВОМ СЛУЧАЕ:

Запустите камеру, передав изображение Uri, где вы хотите сохранить:

String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/picture.jpg";  
File imageFile = new File(imageFilePath); 
Uri imageFileUri = Uri.fromFile(imageFile); // convert path to Uri

Intent it = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
it.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri); 
startActivityForResult(it, CAMERA_RESULT);

В onActivityResult получите изображение как:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if (RESULT_OK == resultCode) { 
        iv = (ImageView) findViewById(R.id.ReturnedImageView); 

        // Decode it for real 
        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
        bmpFactoryOptions.inJustDecodeBounds = false; 

        //imageFilePath image path which you pass with intent 
        Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); 

        // Display it 
        iv.setImageBitmap(bmp); 
    }    
} 
<Ч />

2. Во втором случае:

Запустите камеру без передачи изображения Uri, если вы хотите получить изображение в Intent (данные):

Intent it = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
startActivityForResult(it, CAMERA_RESULT); 

В onActivityResult получить изображение как:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if (RESULT_OK == resultCode) { 
        // Get Extra from the intent 
        Bundle extras = data.getExtras(); 
        // Get the returned image from extra 
        Bitmap bmp = (Bitmap) extras.get("data"); 

        iv = (ImageView) findViewById(R.id.ReturnedImageView); 
        iv.setImageBitmap(bmp); 
    } 
} 

<ч /> ***** Удачного кодирования !!!! *****

4 голосов
/ 06 июля 2012

На событии нажатия кнопки камеры вы можете попробовать это:

final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(getTempFile(this)));
        startActivityForResult(intent, TAKE_PHOTO_CODE);

        declare TAKE_PHOTO_CODE globally as:
        private static final int TAKE_PHOTO_CODE = 1;

Добавьте функцию getTempFile в код, который поможет сохранить изображение с именем myImage.png, которое вы щелкнули в SD-карте в папке, названной какИмя пакета вашего приложения.

private File getTempFile(Context context) {
        final File path = new File(Environment.getExternalStorageDirectory(),
                context.getPackageName());
        if (!path.exists()) {
            path.mkdir();
        }
        return new File(path, "myImage.png");
    }

Теперь в функцию OnActivityResult добавьте следующее:

if (requestCode == TAKE_PHOTO_CODE) {
                final File file = getTempFile(this);
                try {
                    Uri uri = Uri.fromFile(file);
                    Bitmap captureBmp = Media.getBitmap(getContentResolver(),
                            uri);
                    image.setImageBitmap(captureBmp);
                    } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

на случай, если возникнут проблемы с памятью, чем добавить следующий код:

@Override
    protected void onPause() {
        image.setImageURI(null);
        super.onPause();
    }

Я надеюсь, что это поможет вам

3 голосов
/ 06 июля 2012

Я подозреваю, что 3 возможные проблемы могли создать вашу проблему:

  1. Некоторые устройства возвращают null при вызове extras.get("data"); в методе onActivityResult, поэтому ваша проблема может быть NullPointerException.Чтобы решить эту проблему, вам нужно передать точное URI местоположение, чтобы указать приложению камеры, где вы хотите его сохранить, и использовать его в onActivityResult, чтобы получить изображение как Bitmap.

  2. Возможно, ваша деятельность уничтожена GC, поэтому вы должны использовать onSavedInstanceState и onRestoreInstanceState для сохранения данных Activity.См. Ответ этого предыдущего поста для получения дополнительной информации.

Я не знаю, если вы уже имели дело с этими проблемами.

Надеждаэто помогает:)

1 голос
/ 02 июля 2012

Во-первых, не забудьте проверить код запроса, возможно, вы ловите чужой результат там.Во-вторых, не используйте растровое изображение данных намерения - во всяком случае, оно маленькое, но, поскольку вы указываете путь для сохранения захваченного изображения, его там даже не должно быть (см. здесь ).Таким образом, сохраните URL-адрес, который вы указали в качестве пути к выходному файлу, и прочитайте Bitmap оттуда, когда вы получили RESULT_OK для вашего запроса:

    ...
    // save your file uri, not necessarily static
    mUriSavedImage = Uri.fromFile(output);
    startActivityForResult(camera, MY_REQUEST_CODE);
    /* Make a String like "com.myname.MY_REQUEST_CODE" and hash it into int to give it
    a bit of uniqueness */
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
             Bitmap bmp = BitmapFactory.decodeFile(mUriSavedImage);
             if (bmp != null) {
                 image.setImageBitmap(bmp); // Set imageview to image that was
                                // captured
                 image.setScaleType(ScaleType.FIT_XY);
             } else {
                 Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show();
             }
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}
0 голосов
/ 28 марта 2019

Для устройств Samsung добавьте одну строку в свой файл AndroidManifest.xml

android: configChanges = "direction | screenSize"

iнадеюсь, что это будет работать для вас

0 голосов
/ 07 декабря 2015

Привет всем, что я знаю, ответ был дан, но так как это также одно из самых простых решений, которое я когда-либо нашел

Вот пример, который беспокоит само устройство!

AndroidCameraUtils - Загрузите проект и из проекта библиотеки, включив его ниже, фрагмент кода, который вы можете использовать!

private void setupCameraIntentHelper () {mCameraIntentHelper = new CameraIntentHelper (это новый CameraIntentHelperCallback (это.*

@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    mCameraIntentHelper.onSaveInstanceState(savedInstanceState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    mCameraIntentHelper.onRestoreInstanceState(savedInstanceState);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    mCameraIntentHelper.onActivityResult(requestCode, resultCode, intent);
}
}

ПРИМЕЧАНИЕ : - Я пробовал много примеров использования утилит и, конечно, есть и другие способы справиться с этим, но для новичков и людей, которые не слишком знакомы с основными понятиями, было бы большекомфорт с этим проектом. Спасибо!

0 голосов
/ 17 января 2015

Выполните действия, указанные в этой ссылке . Надеюсь, это полезно для вас.

OR

Получение изображения без сбоев

Введите приведенный ниже код в MainActivity

// Storage for camera image URI components 
private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath";      
private final static String CAPTURED_PHOTO_URI_KEY = "mCapturedImageURI"; 

// Required for camera operations in order to save the image file on resume.    
private String mCurrentPhotoPath = null; 
private Uri mCapturedImageURI = null; 

@Override 
public void onSaveInstanceState(Bundle savedInstanceState) { 
   if (mCurrentPhotoPath != null) {            
     savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath); 
   } 
  if (mCapturedImageURI != null) {  
     savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, mCapturedImageURI.toString()); 
  } 
  super.onSaveInstanceState(savedInstanceState); 
} 

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) {

   if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) {
       mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY); 
   } 
   if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) {
   mCapturedImageURI = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY)); 
   } 
   super.onRestoreInstanceState(savedInstanceState); 
}
0 голосов
/ 25 января 2012

Я столкнулся с той же проблемой. По-видимому, исправление состоит в том, чтобы сделать uriSavedImage статическим. Не уверен, что это лучший способ. Но это работает для меня.

...