1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > android调用摄像头拍照的功能实现

android调用摄像头拍照的功能实现

时间:2019-08-07 08:43:28

相关推荐

android调用摄像头拍照的功能实现

该功能使用到的场景比较多,下面能过一个实例介绍其使用,布局比较简单只有两个控件,上面Button下面ImageView,Button用于打开摄像头进行拍照,而ImageView用于将拍到的图片显示出来。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

public class CameraTestActivity extends AppCompatActivity {

public static final int TAKE_PHOTO = 1;

private ImageView picture;

private Uri imageUri;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_camera_test);

Button takePhoto = (Button)findViewById(R.id.take_photo);

picture = (ImageView)findViewById(R.id.picture);

takePhoto.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

File outputImage = new File(getExternalCacheDir(), "output_image.jpg");

try{

if (outputImage.exists()){

outputImage.delete();

}

outputImage.createNewFile();

}catch (IOException e){

e.printStackTrace();

}

if (Build.VERSION.SDK_INT >= 24){ //android7.0及以上

imageUri = FileProvider.getUriForFile(CameraTestActivity.this,

"com.example.cameratest.fileprovider", outputImage);

}else {

imageUri = Uri.fromFile(outputImage);

}

//启动相机程序

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

startActivityForResult(intent, TAKE_PHOTO);

}

});

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

switch (requestCode){

case TAKE_PHOTO:

if (resultCode == RESULT_OK){

try {

Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));

picture.setImageBitmap(bitmap);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

break;

default:

break;

}

}

}

首先创建一个File对象,用于存放摄像头拍下的图片,这里将图片命名为output_image.jpg,并将它存放在手机SD卡的应用关联缓存目录下。什么叫做应用关联缓存目录呢?就是指SD卡中专门用于存放当前应用缓存数据的位置,调用getExternalCacheDir()方法可以得到这个目录,具体的路径是/sdcard/Android/data/(package name)/cache。那么为什么要使用应用关联缓存目录来存放图片呢?因为从Android6.0系统开始,读写SD卡被列为危险权限,如里将图片存放在SD卡的任何其它目录,都要进行运行时权限处理才行,而使用应用关联目录则可以跳过这一步。

接着进行一个判断,如果运行设备的系统版本低于Android7.0,就调用Uri的fromFile()方法将File对象转换成Uri对象,这个Uri对象标识着output_image.jpg这张图片的本地真实路径。否则,就调用FileProvider的getUriForFile()方法将File对象转换成一个封装过的Uri对象。之所以要进行这样一层转换,是因为从Android7.0系统开始,直接使用本地真实路径的Uri被认为是不安全的,会抛出一个FileUriExposedException异常。而FileProvider是一种特殊的内容提供器,它使用了和内容提供器类似的机制来对数据进行保护,可以选择性地将封装过的Uri共享给外部,从而提高了应用的安全性。

因为使用到了内容提供器FileProvider,自然需要在AndroidManifest.xml中进行注册。

1

2

3

4

5

...

<provider android:authorities="com.example.cameratest.fileprovider" android:exported="false" android:granturipermissions="true" android:name="android.support.v4.content.FileProvider">

<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths">

</meta-data></provider>

...

其中,android:name属性的值是固定的,android:authorities属性的值必须要和刚才FileProvider.getUriForFile()方法中的第二个参数一致。另外,这里还在 标签内部使用 来指定Uri的共享路径,并引用了一个@xml/file_paths资源。这个资源的内容如下:

1

2

3

4

<code><code><!--?xml version="1.0" encoding="utf-8"?-->

<paths xmlns:android="/apk/res/android">

<external-path name="my_images" path="">

</external-path></paths></code></code>

其中,external-path就是用来指定Uri共享的,name属性的值可以随便填,path属性的值表示共享的具体路径。这里设置空值就表示将整个SD卡进行共享,当然也可仅共享我们存放output_image.jpg这张图片的路径。

另外还有一点要注意,在Android4.4系统之前,访问SD卡的应用关联目录也是要声明权限的,从4.4系统开始不再需要权限声明。那么我们为了兼容老版本系统的手机,还需要在清单文件中声明一下访问SD卡的权限:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。