拍照PhotoIntentActivity总结

拍照PhotoIntentActivity总结

项目地址:http://developer.android.com/training/camera/photobasics.html

低版本使用高版本的api

1.1 起因

比如在gradle配置文件里:

17102239_CNZw.jpg 

 

再看getExternalStoragePublicDirectory()方法

17102239_HH9o.jpg 

 

也就是说,这个方法在api level 8中才添加进来的,而我的app需要在最小版本4中使用,如果直接使用这个方法,那个android studio会报错,编译不过去。

 

纠正:这里用api level 4也不行,最后改成7,好像是

17102239_Z1wy.jpg 

这个v7包,最小是7

1.2 TargetApi注解

以上问题可以使用TargetApi注解来解决,如下

 

17102239_YQaO.jpg 

这里还需要注意一个问题,这里的compileSdkVersion也是不能小于8的,如果小于8

 

17102240_50Bx.jpg 

这里的FROYO的值是取不到的,假如我取4,那么在Build.VERSION_CODES里,只能取到1234这四个值

这里还需要进一步的处理

 

17102240_kK9k.jpg 

 

这里先判断当前的版本号的大小,来进行不同的操作

 

1.3 Best Practice

这个app中为了获得相册的目录,使用的抽象类,在使用的类中定义一个成员变量,根据版本号不同,使用这个抽象类的子类进行实例化。【这里用接口(Interface)是否也可以呢】

抽象类:

17102240_i13G.jpg 

 

两个实现类:

17102241_qxif.jpg 

 

17102242_dRv3.jpg 

 

成员变量:

17102242_J4OJ.jpg 

 

使用类是根据不同的版本在onCreate中进行实例化:

17102243_GoK4.jpg 

 

隐式intent

调用手机的摄像头进行拍照,发送的是隐式的intent,不指定具体的activity。那么就存在这样的情况:手机上的所有app都不能处理这个intent,那么我的app就会crash。所以在发隐式intent前,必须检查是否存在能够处理这个隐式intentapp,如存在,那么可以发这个intent,如果不存在,那么就不允许发这个intent

2.1 检查方法1

17102244_M3X8.jpg 

 

直接通过resolveActivity方法来判断是否存处理在给定actionintentactivity

 

下面更是指出验证的重要性:如果在使用隐式intent调用 startActivityForResult(),而且这个intent没有app能够处理,appcrash

2.2 检查方法2

这个方法是sample里给出的,核心代码:

17102246_DOpq.jpg 

 

通过PackageManager查找是否存处理在给定actionintentactivity

 

拍小图片(Get the Thumbnail

3.1 发intent

17102247_4SM4.jpg 

这里直接发送actionMediaStore.ACTION_IMAGE_CAPTUREintent,就会调用系统的相机app来进行拍照。

Ps.发之前要检查隐式intent,如第2部分描述。

3.2 获得返回的图片

17102248_XaMI.jpg 

3.1的方法直接发送intent,这里直接从返回的Intent对象获得Bundle对象,再从Bundle对象中取“data”属性,其内容就是拍照的图片

 

The Android Camera application encodes the photo in the return Intent delivered to onActivityResult() as a small Bitmap in the extras, under the key "data".

17102248_jzFo.jpg 

这种方法只适合用于获取小图片

拍大图片(Save the Full-size Photo

拍大图片与拍小图片的区别是,需要把拍的照片缓存到sd卡上,然后再从sd卡读取这张照片进行处理。而不是直接从data中取出照片。

缓存到sd卡上之后,还需要找到它,所以在Activity里声名了一个保存这个路径的成员变量

17102248_m2Xh.jpg 

4.1 发intent

与拍小图片不同,拍大图片需要额外工作

17102249_Fzp7.jpg 

 

结合图中的注释,这里可以看到整个发intent请求的过程

 

1) 与拍小图片一样,先声名一个拍照的intent

2) 获得一个空的临时文件

3) 把这个临时文件的绝对路径保存的activity对象的成员变量中

4) 指定把拍照的图片保存到那个临时文件中

5) 发送intent

 

这里面涉及到很多知识点:文件操作、Uricontentprovider),这里不是主要的内容,不做介绍

4.2 获得返回的数据

由于这里已经把拍照得到的图片放到sd卡中缓存,所以直接从图片路径就可以获得该图片了,但是可以添加一些额外工作

4.2.1 解码图片并缩放(Decode a Scaled Image

为了防止省内存,一般不直接解码得到整个图片,而是把图片按一定的比例进行缩放再解码。

 

Step 1 获得ImageView的大小

 

17102250_Bibw.jpg 

 

Step 2 获得Bitmap的大小

 

17102251_vBkT.jpg 

 

这里 bmOptions.inJustDecodeBounds = true;就是为了得到大小,而不真正得到Bitmap对象

 

 

Step 3 缩放并解码得到Bitmap图片对象

 

17102251_LXrD.jpg 

 

 

4.2.2 添加到画廊(Add the Photo to a Gallery

17102252_ZiP9.jpg 

17102252_R4cc.jpg 

 

生命周期的应用

5.1 保存bitmap再显示bitmap

17102253_lQSi.jpg 

这两个方法,可以保证在横竖屏切换的时候,显示的图片仍然显示,如果不加这两个方法,那么横竖屏切换的时候,imageview上会不再显示图片。

可以看到,在save的时候,把图片保存到bundle中,restore的时候,再从bundle中取出来,设置到imageview中。

5.2 super方法的调用顺序

 

onSaveInstanceState方法的默认实现解释如下

17102254_xocX.jpg 

 

简而言之,这个方法会默认把界面上的view保存起来,如果在override这个方法时,不调用super方法,就需要手动保存这些view

 

所以5.1中看到的方法中,需要先手动把成员变量mImageBitmap保存起来,再调用super的方法

 

onRestoreInstanceState方法的默认实现解释如下

17102254_BLp4.jpg 

 

默认就是把onSaveInstanceState方法保存的view的状态还原回来

 

所以,这里在重写onSaveInstanceStateonRestoreInstanceState时,在onSaveInstanceState中是最后执行super方法,在onRestoreInstanceState是最先执行super方法。

 


 

来自为知笔记(Wiz)


 

转载于:https://my.oschina.net/neumeng/blog/402777

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值