如何在 Android 上使用 MediaStore 将数据从相机保存到磁盘?

发布于 2024-07-14 21:56:46 字数 1490 浏览 11 评论 0原文

对于我的应用程序,我一直在使用自己的 Camera 类来拍摄图像和自己的数据库,但很快我就无法真正跟上变化,我决定使用 Android 中的内置相机应用程序来完成这项工作,但是我似乎无法让它保存文件。 我在这里缺少什么? 应用程序似乎保存了文件,但它只有 0 字节。 我查找了相机应用程序的源代码,它正在 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());
        }
    }


}

For my application, I'd been using my own Camera class for taking images and my own database but soon enough I couldn't really keep up with changes and I decided to use the built in camera application in Android to do the job, but I can't seem to get it to save file. What am I missing here? The application seems to save the file but it's just 0 bytes. I looked up the source code of the Camera application and it's looking for the "output" in Extras to save the file. Any help would be greatly appreciated.

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


}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

╭⌒浅淡时光〆 2024-07-21 21:56:46

这适用于以下代码,当然我对最后一个代码有点愚蠢。 我仍然认为必须有更好的方法,以便原始图像仍然保存在某个地方。 它仍然向我发送较小的 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 的纸杯蛋糕版本应该很快就会修复小图像尺寸的问题。

This worked with the following code, granted I was being a little dumb with the last one. I still think there's got to be a better way so that the original image is still saved somewhere. It still sends me the smaller 25% size image.

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) {
            //
        }
    }
}

Also, I do know that the cupcake release of Android should fix the small image size soon.

如若梦似彩虹 2024-07-21 21:56:46

下面的代码将启动默认相机并使相机将图像保存到指定的 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);

The below code will start the default camera and have the camera save the image to the specified uri. The key is to put the extra "MediaStore.EXTRA_OUTPUT" along with the desired 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);
浅笑轻吟梦一曲 2024-07-21 21:56:46

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

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

In your first attempt, it could be that the Camera app crashes when it reads your "output" extra, since it expects it to be a Uri, while you provide a String. The Camera app seems to read the extra flag after capturing the photo. You should just provide uri, and not uri.getPath(). Then, since you already know the URI to the photo, it will not be returned in the onResult call. You need to remember the URI in a member variable.

In the second attempt you will get a scaled down (50%) bitmap back. It is primarily intended for views. I think the full sized bitmap is too large for the memory budget of the application. This may be the reason for the downscale.

余生共白头 2024-07-21 21:56:46

仅供参考,在文档中找到了这个:
调用者可以传递额外的 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 分支出来,并带有一个总是以低分辨率保存图像的错误。 您可以为相机进行午餐活动,并使用相机的共享功能来使用全尺寸图像。

FYI , found this on docs :
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri value of EXTRA_OUTPUT.

located here :http://developer.android.com/reference/android/provider/MediaStore.html

so the app can save full size image for you , if you tell it where.

**Edit : This is not the case with HTC devices. HTC (not nexus) that uses htc sense ui have branched from android 1.5 and carry a bug that always save the image in low res. you can lunch activity for camera and use the share function from camera to use the full sized image.

夜空下最亮的亮点 2024-07-21 21:56:46

我的模拟器也遇到同样的问题,
我在真正的手机上尝试过,它有效,
也许是因为虚拟手机不能真正拍照。

I got the same Problem with the Emulator,
I tried it on a real Phone an it worked,
maybe it is because the Virtual Phone can't really take Picures.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文