如何使用Android上的MediaStore将数据从Camera保存到磁盘?

时间:2009-03-16 02:22:39

标签: android camera android-intent mediastore

对于我的应用程序,我一直在使用我自己的Camera类来拍摄图像和我自己的数据库,但很快就无法跟上变化,我决定使用Android内置的相机应用程序来完成工作,但我似乎无法得到它来保存文件。我在这里错过了什么?该应用程序似乎保存文件,但它只是0字节。我查找了Camera应用程序的源代码,并在Extras中查找“输出”以保存文件。任何帮助将不胜感激。

Public class CameraTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button cameraButton = (Button) findViewById(R.id.cameraButton);
        cameraButton.setOnClickListener( new OnClickListener(){
            public void onClick(View v ){
                ContentValues values = new ContentValues();
                values.put(Images.Media.TITLE, "title");
                values.put(Images.Media.BUCKET_ID, "test");
                values.put(Images.Media.DESCRIPTION, "test Image taken");
                Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra("output", uri.getPath());
                startActivityForResult(intent,0);
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode== 0 && resultCode == Activity.RESULT_OK){
            ((ImageView)findViewById(R.id.pictureView)).setImageURI(data.getData());
        }
    }


}

5 个答案:

答案 0 :(得分:15)

这适用于下面的代码,因为我对最后一个代码感到有些愚蠢。我仍然认为必须有一个更好的方法,以便原始图像仍然保存在某个地方。它仍然向我发送较小的25%图像。

public class CameraTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button cameraButton = (Button) findViewById(R.id.cameraButton);
    cameraButton.setOnClickListener( new OnClickListener(){
        public void onClick(View v ){

            Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

            startActivityForResult(intent,0);
        }
    });

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode== 0 && resultCode == Activity.RESULT_OK) {
        Bitmap x = (Bitmap) data.getExtras().get("data");
        ((ImageView)findViewById(R.id.pictureView)).setImageBitmap(x);
        ContentValues values = new ContentValues();
        values.put(Images.Media.TITLE, "title");
        values.put(Images.Media.BUCKET_ID, "test");
        values.put(Images.Media.DESCRIPTION, "test Image taken");
        values.put(Images.Media.MIME_TYPE, "image/jpeg");
        Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
        OutputStream outstream;
        try {
            outstream = getContentResolver().openOutputStream(uri);
            x.compress(Bitmap.CompressFormat.JPEG, 70, outstream);
            outstream.close();
        } catch (FileNotFoundException e) {
            //
        } catch (IOException e) {
            //
        }
    }
}

此外,我知道Android的蛋糕版本应该很快就能确定小图像尺寸。

答案 1 :(得分:6)

以下代码将启动默认摄像头并让摄像头将图像保存到指定的uri。关键是将额外的“MediaStore.EXTRA_OUTPUT”与所需的uri放在一起。

File file = new File(Environment.getExternalStorageDirectory().getPath() + "/Images/" + image_name + ".jpg");
Uri imageUri = Uri.fromFile(file);

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

startActivityForResult(intent, 0);

答案 2 :(得分:4)

在您的第一次尝试中,可能是Camera应用程序在读取您的“输出”额外时崩溃,因为它期望它是一个Uri,而您提供一个字符串。相机应用程序似乎在捕获照片后读取额外的标记。你应该只提供uri,而不是uri.getPath()。然后,由于您已经知道照片的URI,因此不会在onResult调用中返回它。您需要记住成员变量中的URI。

在第二次尝试中,您将获得缩小(50%)的位图。它主要用于视图。我认为全尺寸位图对于应用程序的内存预算来说太大了。这可能是缩减规模的原因。

答案 3 :(得分:4)

仅供参考,在文档中找到了这个: 调用者可以传递额外的EXTRA_OUTPUT来控制该图像的写入位置。如果EXTRA_OUTPUT不存在,则在额外字段中返回小尺寸图像作为Bitmap对象。这对于只需要小图像的应用程序非常有用。如果存在EXTRA_OUTPUT,则将将全尺寸图像写入EXTRA_OUTPUT的Uri值。

位于此处:http://developer.android.com/reference/android/provider/MediaStore.html

因此,如果你告诉它在哪里,应用程序可以为你保存完整尺寸的图像。

**编辑:HTC设备不是这种情况。使用htc sense ui的HTC(不是nexus)已经从android 1.5分支并带有一个总是以低分辨率保存图像的bug。您可以在相机的午餐活动中使用相机的共享功能来使用全尺寸图像。

答案 4 :(得分:0)

我遇到了与仿真器相同的问题, 我在真正的手机上尝试过它有效, 也许是因为虚拟电话无法真正拍摄Picures。