如何将相机结果作为数据文件夹中的 uri 获取? [英] How to get camera result as a uri in data folder?

查看:22
本文介绍了如何将相机结果作为数据文件夹中的 uri 获取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个应用程序,我想在其中捕获图像,然后将该图像作为附件发送到电子邮件中.

I am creating an application in which I want to capture a image and then I want to send that image in the email as a attachment.

我正在使用 android.provider.MediaStore.ACTION_IMAGE_CAPTURE 意图操作打开相机,并将文件的 Uri 作为参数传递给 EXTRA_OUTPUT 以获取图像到文件.这是完美的工作,如果我使用 external storage uri 作为 EXTRA_OUTPUT ,我能够获得捕获的图像,但如果我使用数据文件夹 uri 它不起作用,并且相机没有关闭,所有按钮都不起作用.

I am opening a camera using android.provider.MediaStore.ACTION_IMAGE_CAPTURE intent action and I am passing the Uri of the file as a parameter EXTRA_OUTPUT to get the image back to the file. This is working perfectly and I am able to get the captured image if I use the external storage uri as a EXTRA_OUTPUT but if I use the data folder uri it is not working and the camera is not closing and its all buttons are not working.

这是我在外部存储目录中获取结果的代码

Here is my code for get the result in the external storage directory

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File out = Environment.getExternalStorageDirectory();
out = new File(out, imagename);
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(i, CAMERA_RESULT);

此代码用于获取数据文件夹中的图像

And this code is for get the image in the data folder

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File out = getFilesDir();
out = new File(out, MyPharmacyOptions.PRESCRIPTION_IMAGE_NAME);
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(i, CAMERA_RESULT);

我知道 data 文件夹不能被第三个应用程序访问,所以这可能会导致问题,所以我创建了一个内容提供程序来共享文件.

I knew that the data folder is not accessible to third application so may be this causes an issue so I have create one content provider to share the file.

这是我的内容提供类

public class MyContentProvider extends ContentProvider {
    private static final String Tag = RingtonContentProvider.class.getName();
    public static final Uri CONTENT_URI = Uri
            .parse("content://x.y.z/");
    private static final HashMap<String, String> MIME_TYPES = new HashMap<String, String>();

    static {
        MIME_TYPES.put(".mp3", "audio/mp3");
        MIME_TYPES.put(".wav", "audio/mp3");
        MIME_TYPES.put(".jpg", "image/jpeg");
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public String getType(Uri uri) {
        String path = uri.toString();

        for (String extension : MIME_TYPES.keySet()) {
            if (path.endsWith(extension)) {
                return (MIME_TYPES.get(extension));
            }
        }

        return (null);
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode)
            throws FileNotFoundException {
        File f = new File(getContext().getFilesDir(), uri.getPath());

        if (f.exists()) {
            return (ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY));
        }

        throw new FileNotFoundException(uri.getPath());
    }

    @Override
    public Cursor query(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sort) {
        throw new RuntimeException("Operation not supported");
    }

    @Override
    public Uri insert(Uri uri, ContentValues initialValues) {
        File file = new File(getContext().getFilesDir(), uri.getPath());
        if(file.exists()) file.delete();
        try {
            file.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return Uri.fromFile(file);
    }

    @Override
    public int update(Uri uri, ContentValues values, String where,
            String[] whereArgs) {
        throw new RuntimeException("Operation not supported");
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        File f = new File(getContext().getFilesDir(), "image1.jpg");
        if(f.exists()) f.delete();
        f = new File(getContext().getFilesDir(), "image2.jpg");
        if(f.exists()) f.delete();

        getContext().getContentResolver().notifyChange(CONTENT_URI, null);

    }
}

因此,要使用此内容,我将使用以下代码将 uri 传递给相机活动

So to use this content provide I am using following code to pass the uri to the camera activity

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri = MyContentProvider.CONTENT_URI;
uri = Uri.withAppendedPath(uri, imagename);
getContentResolver().insert(uri, null);
getContentResolver().notifyChange(RingtonContentProvider.CONTENT_URI, null);
Log.d(Tag, uri.toString());
i.putExtra(MediaStore.EXTRA_OUTPUT, uri);

startActivityForResult(i, CAMERA_RESULT);

现在,如果我传递 url 以外的外部存储目录,则相机正在打开,但它没有在模拟器中关闭,但在设备中,相机将关闭,但我没有得到结果.

Now if I pass the url other then external storage directory the camera is opening but it is not closing in emulator but in device the camera is going to closed but I am not getting the result.

我已在清单文件中声明此内容提供

I have declared this content provide in the manifest file

<provider
android:name=".contentproviders.MyContentProvider"
android:authorities="x.y.z" />

我还允许写入外部存储以及使用相机.

我可以使用外部存储捕获图像,但我想将图像存储在数据目录而不是外部存储中,因为如果外部存储不可用,我想捕获图像并想发送邮件.

I am able to capture the image using the external storage but I want to store the image in the data directory instead of external storage because if the external storage in not available I want to capture the image and want to send mail.

如果我创建内容提供者,那么我还可以将我的图像分享到电子邮件应用程序.

If I create content provide then I can also share my image to the email application.

如果我们不为相机意图提供额外内容,它将在活动结果中将图像作为字节 [] 作为数据额外内容返回,但这是为了缩略图的目的,所以我无法获得使用这种方式的高分辨率图像.

推荐答案

有两种方法可以解决这个问题.

There are two ways to solve this problem.

1.保存您从 onActivityResult 方法收到的位图

您可以使用以下代码通过 Intent 启动相机以捕获照片

You can start camera through intent to capture photo using below code

Intent cameraIntent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);

拍摄照片后,您将在 onActivityResult 方法中获取位图

After capture photo, you will get bitmap in onActivityResult method

if (requestCode == CAMERA_REQUEST) {  
    Bitmap photo = (Bitmap) data.getExtras().get("data"); 
 }

现在您可以简单地将此位图保存到内部存储器

Now you can simply save this bitmap to internal storage

注意:这里的位图对象由拇指图像组成,它不会有全分辨率图像

2.使用内容提供程序将位图直接保存到内部存储

这里我们将创建内容提供者类以允许本地存储目录对相机活动的权限

Here we will create content provider class to allow permission of local storage directory to camera activity

以下示例提供程序示例

public class MyFileContentProvider extends ContentProvider {
    public static final Uri CONTENT_URI = Uri.parse
                                    ("content://com.example.camerademo/");
    private static final HashMap<String, String> MIME_TYPES = 
                                     new HashMap<String, String>();

    static {
        MIME_TYPES.put(".jpg", "image/jpeg");
        MIME_TYPES.put(".jpeg", "image/jpeg");
    }

    @Override
    public boolean onCreate() {

        try {
            File mFile = new File(getContext().getFilesDir(), "newImage.jpg");
            if(!mFile.exists()) {
                mFile.createNewFile();
            }
            getContext().getContentResolver().notifyChange(CONTENT_URI, null);
            return (true);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    @Override
    public String getType(Uri uri) {
        String path = uri.toString();

        for (String extension : MIME_TYPES.keySet()) {
            if (path.endsWith(extension)) {
                return (MIME_TYPES.get(extension));
            }
        }
        return (null);
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode)
    throws FileNotFoundException {

        File f = new File(getContext().getFilesDir(), "newImage.jpg");
        if (f.exists()) {
            return (ParcelFileDescriptor.open(f,
                    ParcelFileDescriptor.MODE_READ_WRITE));
        }
        throw new FileNotFoundException(uri.getPath());
    }
}

之后,您可以使用以下代码简单地使用 URI 传递给相机活动

After that you can simply use the URI to pass to camera activity using the below code

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, MyFileContentProvider.CONTENT_URI);
startActivityForResult(i, CAMERA_RESULT);

如果您不想创建自己的提供程序,则可以使用 FileProvider 来自 support-library-v4.如需详细帮助,您可以查看 这篇文章

If you don't want to create your own provider then you can use FileProvider from support-library-v4. For detailed help you can look into this post

这篇关于如何将相机结果作为数据文件夹中的 uri 获取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆