• Android---打开相机拍照


    简单实现打开系统系统相机拍一张图片并显示在UI上,适用与个人主页头像的切换。

    1. 添加权限。AndroidManifest.xml里添加使用相机的权限。

    <uses-permission android:name="android.permission.CAMERA"/>

    2. 布局。布局内容比较交单,一个Button用来打开相机;一个ImageView用来接收拍摄的图片。

    1. "1.0" encoding="utf-8"?>
    2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:tools="http://schemas.android.com/tools"
    4. android:layout_width="match_parent"
    5. android:layout_height="match_parent"
    6. tools:context=".MainActivity">
    7. <Button
    8. android:id="@+id/btn_open_gallery"
    9. android:layout_width="150dp"
    10. android:layout_height="75dp"
    11. android:layout_centerHorizontal="true"
    12. android:text="拍照"
    13. android:textSize="20sp"/>
    14. <ImageView
    15. android:id="@+id/img"
    16. android:layout_width="wrap_content"
    17. android:layout_height="wrap_content"
    18. android:layout_centerHorizontal="true"
    19. android:layout_marginTop="10dp"
    20. android:layout_below="@+id/btn_open_gallery"/>
    21. RelativeLayout>

    3. 动态申请权限。Google 在 Android 6.0 开始引入了权限申请机制,除了在AndroidManifest.xml里申请静态权限,还需要在代码里动态申请。这里需要申请系统相机的权限。

    1. /**
    2. * 申请动态权限
    3. */
    4. private void requestPermission() {
    5. if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)
    6. != PackageManager.PERMISSION_GRANTED) {
    7. ActivityCompat.requestPermissions(this,
    8. new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
    9. }else {
    10. takePhoto();
    11. }
    12. }

    4. 申请权限的回调。

    1. /**
    2. * 用户选择是否开启权限操作后的回调;TODO 同意/拒绝
    3. */
    4. @Override
    5. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    6. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    7. if (requestCode == PERMISSION_REQUEST_CODE) {
    8. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    9. // TODO 用户同意开启权限,打开相机
    10. takePhoto();
    11. }else{
    12. Log.d("HL", "权限申请拒绝!");
    13. }
    14. }
    15. }

    5. 创建一个存放拍的照片的文件

    1. /**
    2. * 创建一个存放拍的照片的文件
    3. */
    4. private File createImageFile() throws IOException {
    5. // Create an image file name
    6. String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
    7. .format(new Date());
    8. String imageFileName = "JPEG_" + timeStamp + "_";
    9. Log.d("HL", imageFileName);
    10. File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    11. return File.createTempFile(
    12. imageFileName, /* prefix */
    13. ".bmp", /* suffix */
    14. storageDir /* directory */
    15. );
    16. }

    6. 打开相机。

    1. /**
    2. * 打开相机,选择头像
    3. */
    4. private void takePhoto() {
    5. Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    6. // 确保有一个活动来处理意图
    7. if (takePhotoIntent.resolveActivity(getPackageManager()) != null) {
    8. // 创建保存图片的文件夹
    9. File imageFile = null;
    10. try {
    11. imageFile = createImageFile();
    12. }catch (Exception e){
    13. e.printStackTrace();
    14. }
    15. if (imageFile != null) {
    16. //TODO imageUri 用来接收拍摄的这张照片的真实路径
    17. imageUri = FileProvider.getUriForFile(this, "com.example.takePhoto.fileprovider", imageFile);
    18. }
    19. takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    20. startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST_CODE);
    21. }
    22. }

    7. 结果回调。用户拍了一张图片,接收返回的结果并在ImageView里显示。

    1. @Override
    2. protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    3. super.onActivityResult(requestCode, resultCode, data);
    4. if (requestCode == TAKE_PHOTO_REQUEST_CODE) {
    5. if (resultCode == Activity.RESULT_OK) {
    6. try {
    7. InputStream inputStream = getContentResolver().openInputStream(imageUri);
    8. Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
    9. mImg.setImageBitmap(bitmap);
    10. } catch (Exception e) {
    11. e.printStackTrace();
    12. }
    13. }
    14. }
    15. }

    8.注册内容提供者(Provider)。在 AndroidManifest.xml注册。

    其中,android:name属性值是固定的,android:authorities 属性的值必须要和上面takePhoto()方法里的FileProvider.getUriForFile() 方法中的第二个参数一致,并且该参数固定为"包名(com.xxx.xxx).fileprovider"。另外,这里还有标签的内部使用来指定Uri的共享路径,并引入一个 @xml/file_paths资源。

    在 res -> xml 下创建一个File为“ file_paths”文件,添加以下内容

    1. "1.0" encoding="utf-8"?>
    2. <paths xmlns:android="http://schemas.android.com/apk/res/android">
    3. <external-files-path name="image_path" path="/" />
    4. paths>

    其中,external-path 就是用来指定 Uri 共享的,name 属性可以随便填写,path 属性的值表示共享的具体路径。

    ManiActivity.java 完整代码

    1. package com.example.takephoto;
    2. import androidx.annotation.NonNull;
    3. import androidx.annotation.Nullable;
    4. import androidx.appcompat.app.AppCompatActivity;
    5. import androidx.core.app.ActivityCompat;
    6. import androidx.core.content.ContextCompat;
    7. import androidx.core.content.FileProvider;
    8. import android.Manifest;
    9. import android.app.Activity;
    10. import android.content.Intent;
    11. import android.content.pm.PackageManager;
    12. import android.graphics.Bitmap;
    13. import android.graphics.BitmapFactory;
    14. import android.net.Uri;
    15. import android.os.Bundle;
    16. import android.os.Environment;
    17. import android.provider.MediaStore;
    18. import android.util.Log;
    19. import android.widget.Button;
    20. import android.widget.ImageView;
    21. import java.io.File;
    22. import java.io.IOException;
    23. import java.io.InputStream;
    24. import java.text.SimpleDateFormat;
    25. import java.util.Date;
    26. import java.util.Locale;
    27. public class MainActivity extends AppCompatActivity {
    28. private static final int PERMISSION_REQUEST_CODE = 0;
    29. private static final int TAKE_PHOTO_REQUEST_CODE = 0;
    30. private Uri imageUri;
    31. private ImageView mImg;
    32. private Button mTakePhoto;
    33. @Override
    34. protected void onCreate(Bundle savedInstanceState) {
    35. super.onCreate(savedInstanceState);
    36. setContentView(R.layout.activity_main);
    37. mImg = findViewById(R.id.img);
    38. mTakePhoto = findViewById(R.id.btn_take_photo);
    39. mTakePhoto.setOnClickListener(v -> {
    40. requestPermission();
    41. });
    42. }
    43. /**
    44. * 申请动态权限
    45. */
    46. private void requestPermission() {
    47. if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)
    48. != PackageManager.PERMISSION_GRANTED) {
    49. ActivityCompat.requestPermissions(this,
    50. new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
    51. }else {
    52. takePhoto();
    53. }
    54. }
    55. /**
    56. * 用户选择是否开启权限操作后的回调;TODO 同意/拒绝
    57. */
    58. @Override
    59. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    60. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    61. if (requestCode == PERMISSION_REQUEST_CODE) {
    62. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    63. // TODO 用户同意开启权限,打开相机
    64. takePhoto();
    65. }else{
    66. Log.d("HL", "权限申请拒绝!");
    67. }
    68. }
    69. }
    70. /**
    71. * 打开相机,选择头像
    72. */
    73. private void takePhoto() {
    74. Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    75. // 确保有一个活动来处理意图
    76. if (takePhotoIntent.resolveActivity(getPackageManager()) != null) {
    77. // 创建保存图片的文件夹
    78. File imageFile = null;
    79. try {
    80. imageFile = createImageFile();
    81. }catch (Exception e){
    82. e.printStackTrace();
    83. }
    84. if (imageFile != null) {
    85. //TODO imageUri 用来接收拍摄的这张照片的真实路径
    86. imageUri = FileProvider.getUriForFile(this, "com.example.takePhoto.fileprovider", imageFile);
    87. }
    88. takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    89. startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST_CODE);
    90. }
    91. }
    92. /**
    93. * 创建一个存放拍的照片的文件
    94. */
    95. private File createImageFile() throws IOException {
    96. // Create an image file name
    97. String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
    98. .format(new Date());
    99. String imageFileName = "JPEG_" + timeStamp + "_";
    100. Log.d("HL", imageFileName);
    101. File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    102. return File.createTempFile(
    103. imageFileName, /* prefix */
    104. ".bmp", /* suffix */
    105. storageDir /* directory */
    106. );
    107. }
    108. @Override
    109. protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    110. super.onActivityResult(requestCode, resultCode, data);
    111. if (requestCode == TAKE_PHOTO_REQUEST_CODE) {
    112. if (resultCode == Activity.RESULT_OK) {
    113. try {
    114. InputStream inputStream = getContentResolver().openInputStream(imageUri);
    115. Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
    116. mImg.setImageBitmap(bitmap);
    117. } catch (Exception e) {
    118. e.printStackTrace();
    119. }
    120. }
    121. }
    122. }
    123. }

  • 相关阅读:
    网络安全原理与实践学习笔记——设计DMZ
    plantuml最原始的主题如何设置
    软考高级信息系统项目管理师系列之:信息系统项目管理师论文评分参考标准
    43_Object类
    Ubuntu系统下安装常用软件
    李宏毅-机器学习和深度学习概念入门笔记1
    nohup原理
    Shell 编程之免交互
    iText7高级教程之构建基础块——4.使用AbstractElement对象(part 1)
    golang channel 学习笔记
  • 原文地址:https://blog.csdn.net/qq_44950283/article/details/133076332