Android---打开相机拍照

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

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

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

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn_open_gallery"android:layout_width="150dp"android:layout_height="75dp"android:layout_centerHorizontal="true"android:text="拍照"android:textSize="20sp"/><ImageViewandroid:id="@+id/img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_marginTop="10dp"android:layout_below="@+id/btn_open_gallery"/></RelativeLayout>

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

    /*** 申请动态权限*/private void requestPermission() {if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);}else {takePhoto();}}

4. 申请权限的回调。

    /*** 用户选择是否开启权限操作后的回调;TODO 同意/拒绝*/@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == PERMISSION_REQUEST_CODE) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// TODO 用户同意开启权限,打开相机takePhoto();}else{Log.d("HL", "权限申请拒绝!");}}}

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

    /*** 创建一个存放拍的照片的文件*/private File createImageFile() throws IOException {// Create an image file nameString timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());String imageFileName = "JPEG_" + timeStamp + "_";Log.d("HL", imageFileName);File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);return File.createTempFile(imageFileName,  /* prefix */".bmp",         /* suffix */storageDir      /* directory */);}

6. 打开相机。

    /*** 打开相机,选择头像*/private void takePhoto() {Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 确保有一个活动来处理意图if (takePhotoIntent.resolveActivity(getPackageManager()) != null) {// 创建保存图片的文件夹File imageFile = null;try {imageFile = createImageFile();}catch (Exception e){e.printStackTrace();}if (imageFile != null) {//TODO imageUri 用来接收拍摄的这张照片的真实路径imageUri = FileProvider.getUriForFile(this, "com.example.takePhoto.fileprovider", imageFile);}takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST_CODE);}}

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

 @Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == TAKE_PHOTO_REQUEST_CODE) {if (resultCode == Activity.RESULT_OK) {try {InputStream inputStream = getContentResolver().openInputStream(imageUri);Bitmap bitmap = BitmapFactory.decodeStream(inputStream);mImg.setImageBitmap(bitmap);} catch (Exception e) {e.printStackTrace();}}}}

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

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

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

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

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

ManiActivity.java 完整代码

package com.example.takephoto;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;public class MainActivity extends AppCompatActivity {private static final int PERMISSION_REQUEST_CODE = 0;private static final int TAKE_PHOTO_REQUEST_CODE = 0;private Uri imageUri;private ImageView mImg;private Button mTakePhoto;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mImg = findViewById(R.id.img);mTakePhoto = findViewById(R.id.btn_take_photo);mTakePhoto.setOnClickListener(v -> {requestPermission();});}/*** 申请动态权限*/private void requestPermission() {if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);}else {takePhoto();}}/*** 用户选择是否开启权限操作后的回调;TODO 同意/拒绝*/@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == PERMISSION_REQUEST_CODE) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// TODO 用户同意开启权限,打开相机takePhoto();}else{Log.d("HL", "权限申请拒绝!");}}}/*** 打开相机,选择头像*/private void takePhoto() {Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 确保有一个活动来处理意图if (takePhotoIntent.resolveActivity(getPackageManager()) != null) {// 创建保存图片的文件夹File imageFile = null;try {imageFile = createImageFile();}catch (Exception e){e.printStackTrace();}if (imageFile != null) {//TODO imageUri 用来接收拍摄的这张照片的真实路径imageUri = FileProvider.getUriForFile(this, "com.example.takePhoto.fileprovider", imageFile);}takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST_CODE);}}/*** 创建一个存放拍的照片的文件*/private File createImageFile() throws IOException {// Create an image file nameString timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());String imageFileName = "JPEG_" + timeStamp + "_";Log.d("HL", imageFileName);File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);return File.createTempFile(imageFileName,  /* prefix */".bmp",         /* suffix */storageDir      /* directory */);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == TAKE_PHOTO_REQUEST_CODE) {if (resultCode == Activity.RESULT_OK) {try {InputStream inputStream = getContentResolver().openInputStream(imageUri);Bitmap bitmap = BitmapFactory.decodeStream(inputStream);mImg.setImageBitmap(bitmap);} catch (Exception e) {e.printStackTrace();}}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/86539.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode21合并两个有序链表

题目&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输…

智慧农业农场小程序源码 智慧农场系统源码

智慧农业农场小程序源码 智慧农场系统源码 一、 智慧农场系统的组成 智慧农场系统一般包括传感器、控制器、数据采集与处理平台、应用软件等组成部分。其中, 传感器主要用于采集土壤温度、湿度、光照强度等环境参数,以及作物生长状态、水肥情况等生产信息。控制器则根据传感器…

一个关于 i++ 和 ++i 的面试题打趴了所有人

前言 都说大城市现在不好找工作&#xff0c;可小城市却也不好招人。 我们公司招了挺久都没招到&#xff0c;主管感到有些心累。 我提了点建议&#xff0c;是不是面试问的太深了&#xff0c;在这种小城市&#xff0c;能干活就行。 他说自己问的面试题都很浅显&#xff0c;如果答…

你写过的最蠢的代码是?

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Parseval’s Theorem Parseval’s Identity of Fourier Transform

https://www.tutorialspoint.com/parseval-s-theorem-and-parseval-s-identity-of-fourier-transform

使用PCL进行ICP点云配准

下面代码的功能是&#xff1a;把一个文件夹中所有的pcd文件进行ICP点云配准&#xff0c;并且把每帧结果使用PCL的cloud_viewer进行显示。因为是在ROS下使用&#xff0c;所以还有一个ROS的发布操作(可忽略)。   源码如下&#xff1a; #include <iostream> #include <…

最新AI创作系统+ChatGPT网站源码+支持GPT4.0+支持ai绘画+支持国内全AI模型

一、AI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统&#xff1f;小编这里写一个详细图文教程吧&#x…

Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢

一、前言 Unity 引擎宣布自 2024 年 1 月 1 日起&#xff0c;将根据游戏安装量对开发者进行收费。官网通知如下 收费模式如图 这张图的大致意思就是&#xff0c; 从2024年1月1日开始&#xff0c;Unity将对所有达标的用户&#xff08;开发者&#xff09;根据游戏安装量征收“安…

ES6-扩展运算符“...“

三个连续的句点 … 称为 “展开运算符” (spread operator)&#xff0c;它可以将数组或对象展开成一个列表或一组键值对,常用于组合两个或多个阵列。 组合数组 const arr1 [1, 2, 3]; const arr2 [...arr1, 4, 5, 6]; // [1, 2, 3, 4, 5, 6] 组合对象 const obj1 {a: 1, …

ARM Linux DIY(十三)Qt5 移植

前言 板子带有屏幕&#xff0c;那当然要设计一下 GUI&#xff0c;对 Qt5 比较熟悉&#xff0c;那就移植它吧。 移植 Qt5 buildroot 使能 Qt5&#xff0c;这里我们只开启核心功能 gui module --> widgets module 编译 $ make ODIY_V3S/ qt5base编译报错&#xff1a;找不…

Windows11系统C盘用户文件夹下用户文件夹为中文,解决方案

说明&#xff1a; 1. 博主电脑为Windows11操作系统&#xff0c;亲测有效&#xff0c;修改后无任何影响&#xff0c;软件都可以正常运行&#xff01; 2. Windows10系统还不知道可不可行&#xff0c;因为Windows11的计算机管理中没有本地用户和组&#xff0c;博主在csdn上看到很…

【斗罗2】霍雨浩实力被否定,超级斗罗眼光被嘲,魂导院成功捡漏

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析斗罗大陆2绝世唐门。 最新一集《绝世唐门》已经更新&#xff0c;相信不少小伙伴和小郑一样都已经先睹为快&#xff0c;本集虽然是过渡剧情&#xff0c;但本身还是有不少有意思的剧情&#xff0c;作为过渡文戏也算是可圈可…

网工基础知识——以太网

1972年Bob Metcalfe“以太网之父”被Xerox雇佣为网络专家&#xff0c;Bob Metcalfe 来到Xerox公司的Palo Alto研究中心&#xff08;PARC&#xff09;的第一个任务是把Palo Alto的计算机连接到ARPANET&#xff08;Internet的前身&#xff09;上。1972年底Bob Metcalfe以ALOHA系统…

修改配置maven镜像仓库位置,将maven镜像更换成阿里镜像

大家都知道Maven默认连接的仓库位置https://repo .maven.apache.org/maven2访问国外镜像下载东西时相对较慢&#xff0c;所以多数朋友想切换到国内镜像&#xff0c;国内阿里已经给大家提供了一套完整的镜像供大家使用。 Maven默认连接的仓库位置 <repositories><repos…

【1++的Linux】之进程(三)

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的Linux】 文章目录 一&#xff0c;什么是进程地址空间&#xff1f;二&#xff0c;进程地址空间是怎么设计的&#xff1f;三&#xff0c;为什么要有进程地址空间&#xff1f; 一&#xff0c;什…

【最新!企知道AES加密分析】使用Python实现完整解密算法

文章目录 1. 写在前面2. 过debugger3. 抓包分析4. 断点分析5. Python实现解密算法1. 写在前面 最近华为各方面传递出来的消息无不体现出华为科技实力与技术处于遥遥领先的地位。所以出于好奇想要了解一下咱们国内这些互联网科技企业有哪些技术专利,于是就有了这篇文章! 分析目…

【操作系统】聊聊Linux软中断

什么是中断 中断是系统用来响应硬件设备请求的一种机制&#xff0c;会打断进程的正常调度和执行&#xff0c;转而去执行内核中的中断处理程序。 比如你正在看书&#xff0c;你女朋友叫你出去逛街。你就需要先放下手里的事情&#xff0c;然后逛街。回来之后&#xff0c;在接着看…

Parasoft Jtest 2023.1

Parasoft Jtest 2023.1 2692407267qq.com&#xff0c;更多内容请见http://user.qzone.qq.com/2692407267/

Codeforces Round 848 (Div. 2)C

B. The Forbidden Permutation 一定要注意题目中说的是对于all i满足才算不好的&#xff0c;我们做的时候只要破坏一个i这个a就不算好的了,被这一点坑了&#xff0c;没注意到all。 #include <bits/stdc.h>using namespace std; typedef long long LL; const int N 2e5 …