Android 拍照后相机不保存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26224011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:08:47  来源:igfitidea点击:

Camera is not saving after taking picture

androidandroid-camera

提问by pez

I can press a button, open up the native camera app, and successfully take a picture. But then when I check the Gallery or Photos native apps on my phone, the picture isn't saved there. I'm very new to Android so it's likely I'm missing something important in my code.

我可以按下一个按钮,打开原生相机应用程序,并成功拍照。但是当我检查手机上的图库或照片本机应用程序时,图片并未保存在那里。我对 Android 很陌生,所以很可能我在我的代码中遗漏了一些重要的东西。

Questions:

问题:

1) Where are these pictures being saved?

1)这些图片保存在哪里?

2) Can I modify the below code somehow to save instead to internal storage, so all pictures taken with my app are private and only accessible through my app?

2)我可以修改下面的代码以某种方式保存到内部存储中,所以用我的应用程序拍摄的所有照片都是私人的,只能通过我的应用程序访问吗?

3) If I wanted to save these pictures to an object, along with some text/other input, what would be the best way? Should I just save a Urior some identifier to reference the image later, or save the actual BitMapimage?

3)如果我想将这些图片连同一些文本/其他输入一起保存到一个对象中,最好的方法是什么?我应该只保存一个Uri或一些标识符以稍后引用图像,还是保存实际BitMap图像?

Any help is greatly appreciated, thanks!

非常感谢任何帮助,谢谢!

Here is my code to take the picture:

这是我拍照的代码:

mImageButton.setOnClickListener(new View.OnClickListener()
{
    public void onClick(View v)
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        imageUri = CameraUtils.getOutputMediaFileUri(CameraUtils.MEDIA_TYPE_IMAGE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intent, REQUEST_IMAGE);
    }
}

CameraUtilsclass taken straight from Google developer guides:

CameraUtils直接取自Google 开发者指南的课程:

public static Uri getOutputMediaFileUri(int type)
{
    return Uri.fromFile(getOutputMediaFile(type));
}

public static File getOutputMediaFile(int type)
{
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), "camera");

    if (!mediaStorageDir.exists())
    {
        if (!mediaStorageDir.mkdirs())
        {
            return null;
        }
    }

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE)
    {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "IMG_" + timeStamp + ".jpg");
    }
    else if(type == MEDIA_TYPE_VIDEO)
    {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "VID_" + timeStamp + ".mp4");
    }
    else
    {
        return null;
    }

    return mediaFile;
}

采纳答案by maraci

1) By looking at the code, I'd expect the pictures to be saved in a directory called 'camera' which would be found in the Pictures folder on your device (external storage). These might not instantly appear in your gallery, however in later versions of Android (Kitkat and maybe jelly-bean though I can't verify that right now) you should be able to open the Photos app and find them somewhere in there. If that is not the case, then launch a file explorer app (example apps are ASTRO File Manager or X-Plore) and browse to the Pictures/camera directory where you should see your images. The next time your media gets re-indexed (phone reboot, or a re-index triggered from elsewhere), you should see these pictures in your gallery/photo apps. If you want to refresh your media programatically, heremight help. Finally, make sure you have the READ_EXTERNAL_STORAGE permission in your Android manifest as specified this(Android doc).

1)通过查看代码,我希望图片保存在名为“camera”的目录中,该目录位于设备(外部存储)的图片文件夹中。这些可能不会立即出现在您的图库中,但是在更高版本的 Android(Kitkat 和 jelly-bean,虽然我现在无法验证)中,您应该能够打开照片应用程序并在其中的某个地方找到它们。如果不是这种情况,则启动文件资源管理器应用程序(示例应用程序是 ASTRO 文件管理器或 X-Plore)并浏览到应该可以看到图像的图片/相机目录。下次您的媒体被重新索引(手机重启,或从其他地方触发的重新索引)时,您应该会在图库/照片应用程序中看到这些图片。如果您想以编程方式刷新媒体,请点击此处可能有帮助。最后,确保您的 Android 清单中具有 READ_EXTERNAL_STORAGE 权限,如(Android 文档)所指定。

2) If you want to save images to be only available to your application, you need to save them to your application's internal data directory. Take a look at thisstraight from the Android doc. Make sure to use the MODE_PRIVATE flag.

2) 如果您想将图像保存为仅对您的应用程序可用,您需要将它们保存到您的应用程序的内部数据目录中。直接从 Android 文档中查看此内容。确保使用 MODE_PRIVATE 标志。

3) For this, you would want to store the file path somewhere accessible to your app. Either you could save your file paths to a text file with some other text data, or you could use a sqlite database. Finally, you could use an ORM like ORMLite for Android to save a java object which might hold data for your picture and have some fields you want to persist (title, description, path, etc). Hereand hereis an intro on how to get started with SQLite database in Android (straight from the official doc). If you want to use ORMLite, there is plenty of information on their site here. The developer has spent a lot of time answering StackOverflow questions..

3) 为此,您可能希望将文件路径存储在您的应用可访问的某个位置。您可以将文件路径保存到带有其他文本数据的文本文件中,也可以使用 sqlite 数据库。最后,您可以使用 ORM 之类的 ORM for Android 来保存一个 Java 对象,该对象可能保存您的图片数据并有一些您想要保留的字段(标题、描述、路径等)。这里这里是关于如何在 Android 中开始使用 SQLite 数据库的介绍(直接来自官方文档)。如果你想使用 ORMLite,在他们的网站上有很多信息这里。开发人员花了很多时间回答 StackOverflow 的问题。

All of your questions can be answered with a few simple Google searches. They are very standard and basic things to do in Android, so you should be able to find a plethora of information and tutorials online.

您的所有问题都可以通过一些简单的 Google 搜索得到解答。它们是 Android 中非常标准和基本的操作,因此您应该能够在网上找到大量信息和教程。

EDIT:

编辑

In response to your comment about the second question. This is what I would probably do (or something similar):

回应你对第二个问题的评论。这就是我可能会做的(或类似的事情):

Note that I didn't test this. It's from the top of my head. If you have more issues comment here!

请注意,我没有对此进行测试。它来自我的头顶。如果您有更多问题,请在此处评论!

Activity code...

活动代码...

mImageButton.setOnClickListener(new View.OnClickListener()
{
    public void onClick(View v)
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        imageUri = CameraUtils.getOutputMediaFileUri(currentActivity, CameraUtils.MEDIA_TYPE_IMAGE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intent, REQUEST_IMAGE);
    }
}

public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == REQUEST_IMAGE)
    {
        if (resultCode == RESULT_OK)
        {
            String pathToInternallyStoredImage = CameraUtils.saveToInternalStorage(this, imageUri);
            // Load the bitmap from the path and display it somewhere, or whatever
        }
        else if (resultCode == RESULT_CANCELED)
        {
            //Cancel code
        }
    }
}

CameraUtils class code...

CameraUtils 类代码...

public static Uri getOutputMediaFileUri(int type)
{
    return Uri.fromFile(getOutputMediaFile(type));
}

public static File getOutputMediaFile(int type)
{
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), "camera");

    createMediaStorageDir(mediaStorageDir);

    return createFile(type, mediaStorageDir);
}

private static File getOutputInternalMediaFile(Context context, int type)
{
    File mediaStorageDir = new File(context.getFilesDir(), "myInternalPicturesDir");

    createMediaStorageDir(mediaStorageDir);

    return createFile(type, mediaStorageDir);
}

private static void createMediaStorageDir(File mediaStorageDir) // Used to be 'private void ...'
{
    if (!mediaStorageDir.exists())
    {
        mediaStorageDir.mkdirs(); // Used to be 'mediaStorage.mkdirs();'
    }
} // Was flipped the other way

private static File createFile(int type, File mediaStorageDir ) // Used to be 'private File ...'
{
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile = null;
    if (type == MEDIA_TYPE_IMAGE)
    {
        mediaFile = new File(mediaStorageDir .getPath() + File.separator +
                "IMG_" + timeStamp + ".jpg");
    }
    else if(type == MEDIA_TYPE_VIDEO)
    {
        mediaFile = new File(mediaStorageDir .getPath() + File.separator +
                "VID_" + timeStamp + ".mp4");
    }
    return mediaFile;
}

public static String saveToInternalStorage(Context context, Uri tempUri)
{
    InputStream in = null;
    OutputStream out = null;

    File sourceExternalImageFile = new File(tempUri.getPath());
    File destinationInternalImageFile = new File(getOutputInternalMediaFile(context).getPath());

    try
    {
        destinationInternalImageFile.createNewFile();

        in = new FileInputStream(sourceExternalImageFile);
        out = new FileOutputStream(destinationInternalImageFile);

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0)
        {
            out.write(buf, 0, len);
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
        //Handle error
    }
    finally
    {
        try {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                in.close();
            }
        } catch (IOException e) {
            // Eh
        }
    }
    return destinationInternalImageFile.getPath();
}

So now you have the path pointing to your internally stored image, which you can then manipulate/load from your onActivityResult.

所以现在您有了指向内部存储图像的路径,然后您可以从 onActivityResult 操作/加载该图像。