【问题标题】:Save image from Camera take picture intent to application private storage将来自相机拍照意图的图像保存到应用程序私有存储
【发布时间】:2015-06-09 08:02:19
【问题描述】:

这里有很多关于如何在 android 的外部存储上创建文件,将 uri 传递给 ACTION_IMAGE_CAPTURE 然后将图像保存在那里的信息。

但是,我想在应用程序的私有存储(有时称为内部存储)中创建一个文件并将该文件 uri 传递给 ACTION_IMAGE_CAPTURE 但相机意图在 onActivityResult 中返回 RESULT_CANCELED。

我该怎么办?

private void checkWhetherCameraIsAvailableAndTakeAPicture() {
    // Check wether this device is able to take pictures
    if (PhotoHandler.isIntentAvailable(a, MediaStore.ACTION_IMAGE_CAPTURE)) {
        System.gc();
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File imageFile = null;

        try {
                if(a.application.user.isPublishImagesToGallery()){
                imageFile = a.application.photoHandler.createImageFileOnExternalStorage();
            } else {
                imageFile = a.application.photoHandler.createImageFileOnInternalStorage();
            }

            imagePath = imageFile.getAbsolutePath();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
        } catch (IOException e) {
            e.printStackTrace();
            imageFile = null;
            imagePath = null;
        }
        startActivityForResult(takePictureIntent, Preferences.REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA);
    } else { // Notify the user that their device is unable to take photos
        a.application.toastMaker.toastLong(ErrorMessages.DEVICE_UNABLE_TO_TAKE_PHOTOS);
    }
} // End of checkWhetherCameraIsAvailableAndTakeAPicture

public File createImageFileOnInternalStorage() throws IOException {
        return createTempFileOnGivenLocation();
    }

    private String imageFilename() {
        return filenamePrefix + Calendar.getInstance().getTimeInMillis();
    }

    private File createTempFileOnGivenLocation() throws IOException {
        File imageFile = File.createTempFile(imageFilename(), filenameSuffix, context.getFilesDir());
        setImagePathTemporary(imageFile.toString());

        return imageFile;
    }


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == Preferences.REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA) {
        if (resultCode != Activity.RESULT_CANCELED) {
            handlePhotoTakenWithCamera();
        } else {
            // ONACTIVITYRESULT Returns Here!
            new File(imagePath).delete())
        }
    } else if (requestCode == Preferences.REQUEST_CODE_PICK_IMAGES_FROM_GALLERY) {
        if (resultCode != Activity.RESULT_CANCELED) {
            handlePhotosPickedFromGallery(data);
        }
    }
} // End of onActivityResult

【问题讨论】:

    标签: android android-intent android-camera android-camera-intent


    【解决方案1】:

    内部存储空间对每个应用都是私有的。相机应用程序无法访问您的应用程序的内部存储。在您的内部存储中获取图像的最佳方式是。

    1) 在应用内使用您自己的相机拍摄图像

    2) 使用相机意图拍摄图像以捕获将图像保存到外部存储的图片。 onActivityResult 将图像复制到应用程序的内部存储并从外部存储中删除。复制文件的代码可以在这个答案中找到。 https://stackoverflow.com/a/4770586/4811470

    【讨论】:

    【解决方案2】:

    正如this answer 中所述,相机应用无法直接写入应用的内部存储空间。

    但是,您可以编写一个Content Provider,它将能够将来自相机应用的数据作为流使用并自己保存。

    这是让相机应用知道将文件放在哪里的方法。

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    Uri uri = Uri.withAppendedPath(CONTENT_URI_OF_YOUR_CONTENT_PROVIDER, "id_of_your_image");
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(takePictureIntent, CAMERA_REQUEST);  
    

    恕我直言,如何构建实际的内容提供者有点超出了这个问题的范围。阅读上面链接的文档并搜索相关问题。 一个提示,你必须实现insert 方法才能做到这一点。 它可能看起来像这样。

    public Uri insert(Uri uri, ContentValues values) {
        String name = uri.getPath();
        File file = new File(name);     
        OutputStream stream = new FileOutputStream(file);
        byte[] data = (byte[]) values.get(KEY_FILE_CONTENT);
        try {
            stream.write(data);
            stream.flush();
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return uri;
    }
    

    但由于内容提供程序有多复杂,上面的代码可能无法直接为您工作。

    【讨论】:

    • @J.K.我已经用一些进一步的信息编辑了这个问题。顺便提一句。恕我直言,我的方法优于上一个答案中的方法。您不必自己复制文件,相机通过内容提供商将其直接写入内部存储。 (这也意味着图像可能永远不会存储在公共目录中 - 安全性:) - 但这实际上取决于相机应用程序本身)
    • 非常感谢。如果可以的话我会试试的
    猜你喜欢
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多