Намерение камеры не возвращается к вызывающей активности

#android #android-intent #photo #android-camera-intent

#Android #android-намерение #фото #android-camera-intent

Вопрос:

Я прочитал много вопросов, касающихся этой проблемы. Некоторые из них похожи на то, что я испытываю; Я пробовал ответы, но безуспешно. Код работает на HTC Android 4.2 и не работает на Nexus 7 Android 4.4. Я изменил каталог хранилища для работы на Android 4.4, так что это не проблема.

Намерение камеры никогда не возвращается, если я использую

 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
  

и возвращается, если я использую

 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFile);
  

но это не сохраняет файл.

Вот полный код. Вызовите намерение

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(manager) != null)
{
    try
    {
        final File photoFile = createImageFile();

        if (photoFile != null)
        {
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            //takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFile);
            startActivityForResult(takePictureIntent, 1);
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}
  

Имя файла

 private File createImageFile() throws IOException
{
    if (mStorageDirectory == null)
    {
        createInitialStorageDirectory();
        setupFolders();
        mScrollList.notifyDataSetInvalidated();
    }

    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "slide_"   timeStamp;
    File storageDir = new File(mStorageDirectory);
    File image = File.createTempFile(imageFileName, ".jpg", storageDir);
//        image.setWritable(true, false);

    // Save a path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();
    return image;
}
  

Функция обратного вызова

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1 amp;amp; resultCode == -1)
    {

    }
}
  

Корневой каталог плюс каталог сохранения

 static String mBasePath = "/slides/";

private String getRootDirectory()
{
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state))
    {
        if (Build.VERSION.SDK_INT >= 19)
            return mView.getContext().getFilesDir()   mBasePath;
        else
            return Environment.getExternalStorageDirectory()   "/Android/data/com.hdms.manager"   mBasePath;
        //return Environment.getExternalStorageDirectory()   mBasePath;
    }

    return mBasePath;
}
  

Любые мысли будут оценены.

Ответ №1:

В моем случае он не вернулся, потому что выходной файл находился внутри папки, которую я еще не создал.

Если это относится к кому-то другому, сделайте это перед запуском anintent:

 file.getParentFile().mkdirs();
  

Комментарии:

1. Разве это не ошибка Android framework, что в консоли Android нет IOException (например, nosuchfileordirectoy) или трассировки журнала, чтобы сообщить нам о причине, по которой activity застряла? как мы предполагаем понять, что произошло (кроме открытия stackoverflow …)

Ответ №2:

Итак, я нашел решение своей проблемы. Если файл не существует, то активность камеры не вернется. Я предполагаю, что причина, по которой он не работает на 4.4, заключается в изменении файловой системы. Я не сохраняю изображение в галерее мультимедиа и не загружаю файл обратно в каталог своих приложений. Затем медиафайл удаляется. Причина, по которой я не оставляю его в каталоге мультимедиа, заключается в том, что при удалении приложения будут удалены изображения.

Вот новый код. Сначала вызов намерения

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(manager) != null)
{
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, "New Picture");
    values.put(MediaStore.Images.Media.DESCRIPTION,"From your Camera");
    Uri mImageUri = App.mApplication.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

    mCurrentPhotoPath = mImageUri.getPath();

    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
    startActivityForResult(takePictureIntent, 1);
}
  

Затем обратный вызов.

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

    if (requestCode == 1 amp;amp; resultCode == -1)
    {
        if (data != null)
            mCurrentPhotoPath = String.valueOf(data.getData());

        String[] filePathColumn = {MediaStore.Images.Media.DATA};

        Cursor cursor = App.mApplication.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, filePathColumn, null, null, null);
        if (cursor == null)
            return;
        // find the file in the media area
        cursor.moveToLast();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String filePath = cursor.getString(columnIndex);
        File source  = new File(filePath);
        cursor.close();
        // create the destination file
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "slide_"   timeStamp;
        File destination = new File(mStorageDirectory, imageFileName   ".jpg");

        // copy the data
        if (source.exists())
        {
            try
            {
                FileChannel src = new FileInputStream(source).getChannel();
                FileChannel dst = new FileOutputStream(destination).getChannel();
                dst.transferFrom(src, 0, src.size());
                src.close();
                dst.close();

                source.delete();
            }
            catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}
  

Ответ №3:

В нашем сценарии наше приложение может запускать приложение камеры либо нажатием кнопки, либо нажатием кнопки просмотра изображения. При использовании маршрута кнопки приложение камеры корректно возвращалось к вызывающей активности, как и ожидалось, однако при нажатии на imageview результаты были противоречивыми — иногда оно возвращалось, а иногда приходилось нажимать кнопку «Назад» несколько раз.

Оказывается, решение было моим упущением: я не удалял обработчик событий для imageview в методе onPause — как только я это сделал, он сработал отлично.