简体   繁体   English

拍照后相机未保存

[英]Camera is not saving after taking picture

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? 3)如果我想将这些图片保存到一个对象,以及一些文本/其他输入,那么最好的方法是什么? Should I just save a Uri or some identifier to reference the image later, or save the actual BitMap image? 我应该保存一个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);
    }
}

CameraUtils class 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;
}

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). 1)通过查看代码,我希望将图片保存在名为“camera”的目录中,该目录可以在设备的Pictures文件夹中找到(外部存储器)。 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. 这些可能不会立即出现在您的图库中,但是在Android的更高版本中(Kitkat和果冻豆虽然我现在无法验证)您应该能够打开照片应用并在那里找到它们。 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. 如果不是这样,则启动文件浏览器应用程序(示例应用程序是ASTRO文件管理器或X-Plore)并浏览到您应该看到图像的图片/相机目录。 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, here might help. 如果你想以编程方式刷新你的媒体, 这里可能有帮助。 Finally, make sure you have the READ_EXTERNAL_STORAGE permission in your Android manifest as specified this (Android doc). 最后,确保你有READ_EXTERNAL_STORAGE许可,您的Android清单作为指定 (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. 2)如果要将图像保存为仅适用于您的应用程序,则需要将它们保存到应用程序的内部数据目录中。 Take a look at this straight from the Android doc. 从Android文档中直接看一下这个 Make sure to use the MODE_PRIVATE flag. 确保使用MODE_PRIVATE标志。

3) For this, you would want to store the file path somewhere accessible to your app. 3)为此,您需要将文件路径存储在应用程序可访问的位置。 Either you could save your file paths to a text file with some other text data, or you could use a sqlite database. 您可以将文件路径保存为包含其他文本数据的文本文件,也可以使用sqlite数据库。 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). 最后,您可以使用ORMLite for Android这样的ORM来保存一个java对象,该对象可能包含您的图片数据并且有一些您想要保留的字段(标题,描述,路径等)。 Here and here is an intro on how to get started with SQLite database in Android (straight from the official doc). 这里这里是如何在Android中开始使用SQLite数据库的介绍(直接来自官方文档)。 If you want to use ORMLite, there is plenty of information on their site here . 如果你想使用ORMLite,有大量的信息在其网站上这里 The developer has spent a lot of time answering StackOverflow questions.. 开发人员花了很多时间回答StackOverflow问题。

All of your questions can be answered with a few simple Google searches. 您可以通过一些简单的Google搜索来回答所有问题。 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. 它们是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操作/加载它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM