当前位置: 首页 > news >正文

【安卓】调用摄像头和相册

文章目录

      • 调用摄像头拍照
      • 从相册中选择照片

调用摄像头拍照

  新建一个CameraAlbumTest项目,然后修改activity_main.xml中的代码。在布局文件中添加两个控件:一个Button和一个ImageView。Button是用于打开摄像头进行拍照的,而ImageView则是用于将拍到的图片显示出来。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent" ><Buttonandroid:id="@+id/takePhotoBtn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Take Photo" /><ImageViewandroid:id="@+id/imageView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal" />
</LinearLayout>

  编写调用摄像头的具体逻辑,修改MainActivity中的代码。给Button注册点击事件,然后在点击事件里开始处理调用摄像头的逻辑。

public class MainActivity extends AppCompatActivity {public static final int TAKE_PHOTO = 1;private ImageView picture;private Uri imageUri;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button takePhoto = (Button) findViewById(R.id.takePhotoBtn);picture = (ImageView) findViewById(R.id.imageView);takePhoto.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v) {// 创建File对象,用于存储拍照后的图片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) {imageUri = FileProvider.getUriForFile(MainActivity.this,"com.example.cameraalbumtest.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);}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, 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;}}
}

  getUriForFile()方法接收3个参数:第一个参数要求传入Context对象,第二个参数可以是任意唯一的字符串,第三个参数则是File对象。

  修改AndroidManifest.xml文件。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.CameraAlbumTest"tools:targetApi="31"><providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.example.cameraalbumtest.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

  添加资源文件file_paths.xml。在res文件下找到xml目录(如果没有在res目录下新建目录)新建file,取名file_paths.xml。然后修改file_paths.xml文件中的内容。

<?xml version="1.0" encoding="UTF-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-path name="my_images" path="/" />
</paths>

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

在这里插入图片描述

从相册中选择照片

  修改activity_main.xml文件,在布局中加入一个新按钮。

	<Buttonandroid:id="@+id/fromAlbumBtn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="From Album" />

  然后修改MainActivity中的代码,加入从相册选择图片的逻辑。

public class MainActivity extends AppCompatActivity {public static final int TAKE_PHOTO = 1;private ImageView picture;private Uri imageUri;public static final int CHOOSE_PHOTO = 2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button takePhoto = (Button) findViewById(R.id.takePhotoBtn);Button chooseFromAlbum = (Button) findViewById(R.id.fromAlbumBtn);picture = (ImageView) findViewById(R.id.imageView);takePhoto.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v) {// 创建File对象,用于存储拍照后的图片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) {imageUri = FileProvider.getUriForFile(MainActivity.this,"com.example.cameraalbumtest.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);}});chooseFromAlbum.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v) {if (ContextCompat.checkSelfPermission(MainActivity.this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(MainActivity.this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);} else {openAlbum();}}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, 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;case CHOOSE_PHOTO:if (resultCode == RESULT_OK) {// 判断手机系统版本号if (Build.VERSION.SDK_INT >= 19){// 4.4及以上系统使用这个方法处理图片handleImageOnKitKat(data);} else {// 4.4以下系统使用这个方法处理图片handleImageBeforeKitKat(data);}}break;default:break;}}// 打开相册private void openAlbum() {Intent intent = new Intent("android.intent.action.GET_CONTENT");intent.setType("image/*");startActivityForResult(intent, CHOOSE_PHOTO);   // 打开相册}public void onRequestPermissionResult(int requestCode, String[] permissions,int[] grantREsults){switch (requestCode) {case 1:if (grantREsults.length > 0 && grantREsults[0] == PackageManager.PERMISSION_GRANTED){openAlbum();} else {Toast.makeText(this, "You denied the permission",Toast.LENGTH_SHORT).show();}break;default:break;}}@TargetApi(19)private void handleImageOnKitKat(Intent data) {String imagePath = null;Uri uri = data.getData();if (DocumentsContract.isDocumentUri(this, uri)) {// 如果是document类型的Uri,则通过document id处理String docId = DocumentsContract.getDocumentId(uri);if ("com.android.providers.media.documents".equals(uri.getAuthority())){String id = docId.split(":")[1]; // 解析出数字格式的idString  selection = MediaStore.Images.Media._ID + "=" + id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {Uri contentUri = ContentUris.withAppendedId(Uri.parse("content:" +"//downloads/public_downloads"), Long.valueOf(docId));imagePath = getImagePath(contentUri, null);}} else if ("content".equalsIgnoreCase(uri.getScheme())){// 如果是content类型的Uri,则使用普通方式处理imagePath = getImagePath(uri, null);} else if ("file".equalsIgnoreCase(uri.getScheme())){// 如果是file类型的Uri,直接获取图片路径即可imagePath = uri.getPath();}displayImage(imagePath); // 根据图片路径显示图片}private void handleImageBeforeKitKat(Intent data) {Uri uri = data.getData();String imagePath = getImagePath(uri, null);displayImage(imagePath);}private String getImagePath(Uri uri, String selection) {String path = null;// 通过Uri和selection来获取真实的图片路径Cursor cursor = getContentResolver().query(uri, null, selection, null, null);if (cursor != null) {if (cursor.moveToFirst()) {path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));}cursor.close();}return path;}private void displayImage(String imagePath) {if (imagePath != null) {Bitmap bitmap = BitmapFactory.decodeFile(imagePath);picture.setImageBitmap(bitmap);} else {Toast.makeText(this, "failed to get iamge", Toast.LENGTH_SHORT).show();}}
}

  在AndroidManifest.xml中进行授权

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

  此时运行程序会报一个错:Unable to decode stream: java.io.FileNotFoundException,没查到错是什么原因导致的,但是有解决方法。在application中加一句:

android:requestLegacyExternalStorage=“true”

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Ubuntu18.04 配置EtherCAT主站IGH SOEM
  • css实现水滴效果图
  • MPU6050详细介绍
  • 初始化React Native项目
  • 独立开发者系列(42)——MYSQL语句使用和进阶
  • SQL Server 2022的游标
  • 20240813在荣品RK3588S-AHD开发板的预置Android13中挂载ext4格式的256GB的TF卡
  • 【智能家居设备集成】智能家居设备的集成与互联互通
  • Revit二次开发_使用InnoSetup打包插件
  • Vue2.0 项目实战篇\部署篇
  • B3-111-A 小型挂轨式巡检机器人:智能巡检的突破之
  • MyBatis 配置与测试方式
  • 【纯干货级教程】YOLOv7如何添加注意力机制?
  • 排序算法之折半插入排序
  • 算法的学习笔记—打印从 1 到最大的 n 位数
  • $translatePartialLoader加载失败及解决方式
  • @jsonView过滤属性
  • 0x05 Python数据分析,Anaconda八斩刀
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • Create React App 使用
  • CSS实用技巧
  • ES2017异步函数现已正式可用
  • EventListener原理
  • iOS | NSProxy
  • iOS 颜色设置看我就够了
  • Just for fun——迅速写完快速排序
  • k个最大的数及变种小结
  • nfs客户端进程变D,延伸linux的lock
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • php的插入排序,通过双层for循环
  • rabbitmq延迟消息示例
  • zookeeper系列(七)实战分布式命名服务
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 前端路由实现-history
  • 说说动画卡顿的解决方案
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 学习HTTP相关知识笔记
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​Java基础复习笔记 第16章:网络编程
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • # include “ “ 和 # include < >两者的区别
  • $forceUpdate()函数
  • (12)Hive调优——count distinct去重优化
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (Ruby)Ubuntu12.04安装Rails环境
  • (补充)IDEA项目结构
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (算法)N皇后问题
  • (一)模式识别——基于SVM的道路分割实验(附资源)
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .net 7和core版 SignalR