Android сохранение изображения с помощью родной камеры - PullRequest
4 голосов
/ 18 января 2011

Я хотел бы запустить родную камеру Android и сохранить изображение в указанном месте. Проблема в том, что после того, как я нажму на фотографию, в окне предварительного просмотра появятся параметры «Сохранить / Отменить». После нажатия кнопки «Сохранить» камера запускается снова, и захваченное изображение не сохраняется в указанном месте. Скорее он сохраняется в папке по умолчанию. На самом деле мне нужно местоположение изображения, которое я нажал. Вот код, который я использую для запуска камеры.

MediaScannerConnection_MSC = null;
String fileName = String.valueOf(System.currentTimeMillis())+".jpg";
f = new File(Environment.getExternalStorageDirectory(), fileName);
_imageUri = Uri.fromFile(f);
// create new Intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, _imageUri);
startActivityForResult(intent, 1);

Вот код после возвращения с камеры

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode == RESULT_OK) {
                // use imageUri here to access the image

                final String imagePath = f.getAbsolutePath();
                _MSC = new MediaScannerConnection(this, new MediaScannerConnectionClient() {

                    public void onMediaScannerConnected() {
                        _MSC.scanFile(imagePath, null);
                    }

                    public void onScanCompleted(String path, Uri uri) {
                        _MSC.disconnect();
                        _MSC = null;
                    }

                });
                _MSC.connect();

            }
        }
    }

какую ошибку я здесь делаю

1 Ответ

2 голосов
/ 08 апреля 2011

Я думаю, что у меня есть ваш ответ, я искал высоко и низко этот, и это довольно сложно.

Прежде всего, я думаю, на некоторых телефонах,

intent.putExtra(MediaStore.EXTRA_OUTPUT, _imageUri);

игнорируется: - (

Так что мой лучший ответ для вас - не устанавливайте флаг «EXTRA_OUTPUT», вместо этого пусть он работает нормально и возвращает ваш новый URI изображения. Затем оттуда используйте:

Uri u = intent.getData();

Чтобы получить информацию о вашем новом изображении, затем я использую FileOutputStream, чтобы записать файл изображения в новое местоположение, в которое я хочу его поместить. Затем, наконец, я удаляю оригинальный файл. : -)

Я знаю, что это довольно странно, но это работает, и я думаю, что это довольно надежно. : -)

Надеюсь, это поможет. : -)

-Jared

8-28-11

@ llango J

Хорошо, вот весь код, вы можете скопировать и вставить его и посмотреть, сможете ли вы заставить его работать: -)

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

startActivityForResult(CameraIntent, TAKE_PICTURE);

Тогда для результата вам понадобится:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (resultCode == Activity.RESULT_OK) {
        switch (requestCode) {
        case TAKE_PICTURE:
            Uri u = intent.getData();
            //Toast.makeText(getApplicationContext(), u.getPath(), Toast.LENGTH_SHORT).show();
            WriteFiles(u);
            break;

        }
    }
}

И тогда в этой функции происходит главное волшебство:

private void WriteFiles(Uri myNewPic) {
    String TempFilePath;
    String TempPath;

    File directory = new File("/sdcard/" + getString(R.string.app_name));

    if (!directory.exists()) {
        directory.mkdirs();
    }

    String TempPictureFile;
    try {
        TempPictureFile = myNewPic.getLastPathSegment() + ".jpg";
        TempFilePath = directory.getPath() + "/" + TempPictureFile;
        FileOutputStream myOutStream = new FileOutputStream(TempFilePath);
        InputStream myInStream = getContentResolver().openInputStream(myNewPic);
        FileIO myFileIO = new FileIO();
        myFileIO.copy(myInStream, myOutStream);
        //now delete the file after copying
        getContentResolver().delete(myNewPic, null, null);
        TempFilePaths.add(TempFilePath);
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), getString(R.string.ErrorOpeningFileOutput), Toast.LENGTH_SHORT).show();
    }
}

Я думаю, что это все, что вам нужно, чтобы сохранить с помощью родного приложения камеры. Тем не менее, я должен предупредить вас, что в конечном итоге я отказался от этого кода, потому что мне нужно больше гибкости и надежности, чем это предлагалось (я думаю, что если вы используете это приложение на множестве разных телефонов, я могу видеть, что у него проблемы по одной причине или другой. Как, например, у меня было множество проблем из-за того, что Samsung настраивал их интерфейс, поэтому все отлично работает на всех телефонах, кроме Samsung. :-P). Так что я просто создал собственное приложение для камеры, но я уверен, что в зависимости от вашего приложения это может сработать для вас. В любом случае .... удачи! : -)

Хорошо, вот мой класс FileIO, который я использую, извините, я не включил его изначально:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.util.Log;

public class FileIO {
private static final int BUFFER_SIZE = 1024 * 2;

public FileIO() {
    // Utility class.
}

public int copy(InputStream input, OutputStream output) throws Exception, IOException {
    byte[] buffer = new byte[BUFFER_SIZE];

    BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
    BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
    int count = 0, n = 0;
    try {
        while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
            out.write(buffer, 0, n);
            count += n;
        }
        out.flush();
    } finally {
        try {
            out.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), null);
        }
        try {
            in.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), null);
        }
    }
    return count;
}

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...