文档章节

android调用系统相机拍照

YougaKing
 YougaKing
发布于 2016/09/06 16:17
字数 1459
阅读 1298
收藏 3
点赞 1
评论 4

获取缩略图

直接调取相机拍照,无需任何权限,但是只能获取到缩略图

       Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
       if (takePictureIntent.resolveActivity(getPackageManager()) != null) {//判断是否有相机应用
           startActivityForResult(takePictureIntent, REQ_THUMB);
       }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQ_THUMB://返回结果
                if (resultCode != Activity.RESULT_OK) return;
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                mImageView.setImageBitmap(imageBitmap);
                break;
        }
    }

 图片很模糊。一般不采取此种方式

保存全尺寸照片

调取相机拍照保存一个全尺寸的照片,必须提供完整的文件名,相机应用自动保存照片。此时也无需任何权限,创建一个空的临时文件用来保存图片,使用日期时间戳新照片返回一个唯一的文件名

    String mCurrentPhotoPath;
    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        //.getExternalFilesDir()方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        //创建临时文件,文件前缀不能少于三个字符,后缀如果为空默认未".tmp"
        File image = File.createTempFile(
                imageFileName,  /* 前缀 */
                ".jpg",         /* 后缀 */
                storageDir      /* 文件夹 */
        );
        mCurrentPhotoPath = "file:" + image.getAbsolutePath();
        return image;
    }

每执行一次就会创建一个空的文件

利用上述方法创建的文件只能是自己的app访问,随着app的卸载,文件也会删除。对于Android N以下,文件直接Uri.fromFile(file)就可以直接使用,Audroid N 即编译app的版本 compileSdkVersion 24时,此时会报出FileUriExposedException异常,解释如下:

  • 对于面向 Android N 的应用,Android 框架执行的 StrictMode,API 禁止向您的应用外公开 file://URI。
    如果一项包含文件 URI 的 Intent 离开您的应用,应用失败,并出现 FileUriExposedException异常。

  • 若要在应用间共享文件,您应发送一项 content://URI,并授予 URI 临时访问权限。
    进行此授权的最简单方式是使用 FileProvider类。 如需有关权限和共享文件的更多信息,
    请参阅共享文件

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {//判断是否有相机应用
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();//创建临时图片文件
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                //FileProvider 是一个特殊的 ContentProvider 的子类,
                //它使用 content:// Uri 代替了 file:/// Uri. ,更便利而且安全的为另一个app分享文件
                Uri photoURI = FileProvider.getUriForFile(this,
                        "com.example.android.fileprovider",
                        photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }

现在,需要配置FileProvider。在应用程序的清单,提供者添加到您的应用程序,authorities="applicationId.fileprovider",使用时

Uri photoURI = FileProvider.getUriForFile(context,"applicationId.fileprovider", photoFile)

清单中authorities 和 参数authority保持一致。

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.youga.capturingphotos.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"/>
        </provider>
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.youga.capturingphotos.name/files/Pictures" />
</paths>
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_TAKE_PHOTO://返回结果
                if (resultCode != Activity.RESULT_OK) return;
                mImageView.setImageBitmap(BitmapFactory.decodeFile(mCurrentPhotoPath));
                break;
        }
    }

关于FileProvider

FileProvider 是 ContentProvider 的一个特殊的子类,它有利于安全地分享应用相关的文件,通过对一个文件创建content:// Uri而不是file:/// Uri

由于FileProvider的默认功能包括文件的content URI的生成,你并不需要在代码中定义一个子类。相反,你可以在你的应用中包含一个FileProvider通过在XML文件中指定它。对于指定FileProvider,添加一个<provider>元素在你应用的清单文件中。设置android:name属性为android.support.v4.content.FileProvider。根据你控制的域名设置android:authorities属性为一个URI authority(authorities可以随意填写,但是要保证使用时与authority保持一致,推荐applicationId.fileprovider,以免定义重复)。设置android:exported属性为false;FileProvider不需要公开。设置android:grantUriPermissions属性为true,为了允许你进行临时访问文件的授权。

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.youga.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"/>
</provider>

一个FileProvider只能生成一个content URI 对应你事先指定目录下的文件。对于指定一个目录,使用<paths>元素的子元素,在XML中指定它的存储区域和路径。例如,下面的paths元素告诉FileProvider你打算请求你的私有文件区域的 images/ 子目录的content URIs

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.youga.capturingphotos/files/Pictures/" />
    <external-path name="images" path="Pictures/" />
</paths>

file-path 表示你应用内部存储区域的文件的子目录。这个子目录和getFilesDir()的返回值一样。external-path 表示你应用外部存储区域的文件的子目录。这个子目录和getExternalFilesDir()的返回值一样。cache-path 表示你应用内部存储区域的缓存子目录。这个子目录的根目录和getCacheDir()的返回值一样。(如果你修改了provider和paths中的值,需要把应用卸载重装或者开关机一下才能看到变化。)

照片添加到图库

上述保存全尺寸图片时,创建图片临时文件在目录getExternalFilesDir()中,图库无法访问到,我们可以直接创建文件在Environment.getExternalStorageDirectory()目录下;然后发送一个广播让图库更新就好了。当然也可以直接创建文件在图库目录下(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)),即DCIM。此时需要SD卡读写权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
File path = Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_DCIM);
// Create an image file name
Log.i(TAG, "path:" + path.getAbsolutePath());
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
String imageFileName = "JPEG_" + timeStamp;
File image = File.createTempFile(
        imageFileName,  /* 前缀 */
        ".jpg",         /* 后缀 */
        path      /* 文件夹 */
);
mPublicPhotoPath = image.getAbsolutePath();

同时发送广播

Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mPublicPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);

源码放在github上,https://github.com/YougaKing/CapturingPhotos

© 著作权归作者所有

共有 人打赏支持
YougaKing
粉丝 5
博文 7
码字总数 6795
作品 0
西安
程序员
加载中

评论(4)

YougaKing
YougaKing

引用来自“小白白转小牛牛”的评论

有没有详细一点的源码可以看看 上面的链接打不开@YougaKing 多谢了 小白一个
源码在github上,github一般不会被强,多试几次就好了。https://github.com/YougaKing/CapturingPhotos
小白白转小牛牛
有没有详细一点的源码可以看看 上面的链接打不开@YougaKing 多谢了 小白一个
YougaKing
YougaKing

引用来自“Hideeee”的评论

非常好。 居然没人评论。
多谢支持,:laughing:
Hideeee
Hideeee
非常好。 居然没人评论。
你需要知道的Android拍照适配方案

你需要知道的Android拍照适配方案 字数4229 阅读4284 评论23 喜欢71 声明:本文作者授权微信公众号Android程序员(AndroidTrending)在微信公众号平台原创首发。 近段时间,家里陪自己度过大...

3kqing ⋅ 2016/06/05 ⋅ 0

Android 新老两代 Camera API 大起底

0.背景简介 最近有一部分相机相关的需求,专注于对拍摄的照片、视频的噪点、色温、明暗等方面进行优化。一般我们在生活中使用相机来拍照的话,在前期拍摄时,就可以通过调整相机的拍摄参数,...

byeweiyang ⋅ 05/30 ⋅ 0

调用多媒体功能

Android系统的多媒体功能使用的是MediaStore类,这个类是Android多媒体数据库的封装类。无论我们是调用多媒体功能发送的intent,data,extra等,还是从多媒体数据库存取数据,都要通过这个类。...

亭子happy ⋅ 2014/03/06 ⋅ 0

Android学习笔记系列一 —— 组件的类型

1.Activity 可以单纯的理解为一个页面就是一个Activity。他与用户的交互息息相关,每个Activity在程序中其实是相互独立的,这样带来的好处就是,一个Activity可以被自己所在的程序调用,也可...

微笑的江豚 ⋅ 2016/03/18 ⋅ 0

调用系统相机,相册功能

一开始的思路是这一块的功能单独出去;这样处理又会碰见很多问题. 还是集成在Activity中可能效果更好些, 而且三星的手机调用系统相机会导致调用的Activity会重启生命周期,如果是在fragment中调...

新年 ⋅ 2015/05/06 ⋅ 0

Android 调用系统拍照 笔记

由于临时需要做个简单的Android程序,其中涉及调用系统拍照并保存照片。之前没有任何Java和Android经验,coding中遇到不少问题,特记录以供参考。 Google一下能找到不少现成的调用系统拍照的...

会说话的哑巴 ⋅ 2012/09/07 ⋅ 0

使用 android 的摄像头拍照

android提供了操作摄像头的API,可以通过两种做法来使用: 通过Intent直接调用系统提供的照相机功能,复用它的拍照Activity,这是最简单和最方便的办法,因为你不需要考虑手机的兼容性问题,...

华宰 ⋅ 2011/09/07 ⋅ 0

Android Camera&Matrix图像变换

Camera与Matrix Android UI系统中,Camera充当着相机的角色,无论是系统成像还是UI绘制。都离不开Camera。但是在Android系统中,存在两种Camera,一种是视觉成像的(拍照、摄像),另一种是图...

IamOkay ⋅ 04/04 ⋅ 0

在 Android 版微信中调用系统自带相机拍照 | 一日一技

在 Android 版微信中调用系统自带相机拍照 | 一日一技 少数派2018-01-032 阅读 相机调用Android系统拍照 用 Android 手机的朋友在使用微信时一定都发现一个问题:当你在聊天中点击拍照时,调...

少数派 ⋅ 01/03 ⋅ 0

Android相机开发那些坑

版权声明:本文由王梓原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/168 来源:腾云阁 https://www.qcloud.com/community 最近我负责开发了一个跟And...

偶素浅小浅 ⋅ 2016/11/08 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

一篇文章学懂Shell脚本

Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合。 Shell可以直接使用在win/Unix/Linux上面,并且可以调用...

Jake_xun ⋅ 34分钟前 ⋅ 0

大数据工程师需要精通算法吗,要达到一个什么程度呢?

机器学习是人工智能的一个重要分支,而机器学习下最重要的就是算法,本文讲述归纳了入门级的几个机器学习算法,加大数据学习群:716581014一起加入AI技术大本营。 1、监督学习算法 这个算法由...

董黎明 ⋅ 今天 ⋅ 0

Kylin 对维度表的的要求

1.要具有数据一致性,主键值必须是唯一的;Kylin 会进行检查,如果有两行的主键值相同则会报错。 2.维度表越小越好,因为 Kylin 会将维度表加载到内存中供查询;过大的表不适合作为维度表,默...

无精疯 ⋅ 今天 ⋅ 0

58到家数据库30条军规解读

军规适用场景:并发量大、数据量大的互联网业务 军规:介绍内容 解读:讲解原因,解读比军规更重要 一、基础规范 (1)必须使用InnoDB存储引擎 解读:支持事务、行级锁、并发性能更好、CPU及...

kim_o ⋅ 今天 ⋅ 0

代码注释中顺序更改 文件读写换行

`package ssh; import com.xxx.common.log.LogFactory; import com.xxx.common.log.LoggerUtil; import org.apache.commons.lang3.StringUtils; import java.io.*; public class DirErgodic ......

林伟琨 ⋅ 今天 ⋅ 0

linux实用操作命令

参考 http://blog.csdn.net/qwe6112071/article/details/50806734 ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a 列出包括.a开头的隐藏文件的所有文件-A 同-a,但不列出"."和"...

简心 ⋅ 今天 ⋅ 0

preg_match处理中文符号 url编码方法

之前想过直接用符号来替换,但失败了,或者用其他方式,但有有些复杂,这个是一个新的思路,亲测可用 <?php$str='637朗逸·超速新风王(300)(白光)'; $str=iconv("UTF-8","GBK",$s...

大灰狼wow ⋅ 今天 ⋅ 0

DevOps 资讯 | PostgreSQL 的时代到来了吗 ?

PostgreSQL是对象-关系型数据库,BSD 许可证。拼读为"post-gress-Q-L"。 作者: Tony Baer 原文: Has the time finally come for PostgreSQL?(有删节) 近30年来 PostgreSQL 无疑是您从未听...

RiboseYim ⋅ 今天 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 今天 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部