【问题标题】:Android saving image using native cameraAndroid使用本机相机保存图像
【发布时间】:2011-01-18 09:56:19
【问题描述】:

我想启动原生安卓相机并将图像保存在指定位置。问题是在我单击照片后,预览会出现保存/放弃的选项。单击保存后,相机再次启动,并且我捕获的图像未保存在指定位置。而是将其保存在默认位置。实际上我需要我点击的图像的位置。这是我用来启动相机的代码。

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

            }
        }
    }

我在这里做错了什么

【问题讨论】:

  • 我有一个非常相似的问题。谁能回答这个问题?

标签: android android-camera


【解决方案1】:

我想我有你的答案,我已经为这个问题搜索了高低,这有点棘手。

首先,我认为在某些手机上,

intent.putExtra(MediaStore.EXTRA_OUTPUT, _imageUri);

被忽略:-(

所以我对你的最佳回答是,不要设置“EXTRA_OUTPUT”标志,而是让它正常运行并返回你的新图片 URI。然后,从那里使用:

Uri u = intent.getData();

要获取新图片的信息,然后从那里,我使用 FileOutputStream 将图像文件写入我想要的新位置。然后,最后,我删除了原始文件。 :-)

我知道这有点做作,但它确实有效,而且我认为它非常可靠。 :-)

我希望这会有所帮助。 :-)

-贾里德

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

我认为这是您使用本机相机应用程序保存所需的所有部分。但是,我必须提醒你,我最终放弃了这段代码,因为我需要比它提供的更多的灵活性和可靠性(我想如果你在大量不同的手机上使用这个应用程序,我可能会看到它有问题是有原因的或另一个。例如,由于三星定制了他们的 UI,我遇到了很多问题,因此除了三星手机之外,所有手机都运行良好。:-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;
}

}

【讨论】:

  • 好的,让我试一试,看看效果如何
  • @llango J ,我已经修改并扩展了代码,因此您可以将其复制并粘贴到您的应用程序中。如果这不能为您解决问题,请告诉我。 :-)
  • @Jared 这对我不起作用,首先你试图在不存在的String 上调用add(),此外,你是什么 IO 类使用?
  • @James.Elsey 我刚刚修改了代码以删除那个不存在的字符串。它之所以存在,是因为我不得不对我的原始代码进行大量的修整,以使你们更容易。说到这一点,我已经包含了我正在使用的 FileIO 类,所以你也可以使用它。我希望这会有所帮助! :-)
猜你喜欢
  • 2012-12-20
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
相关资源
最近更新 更多