AndroidStudio相机拍照或从相册中选取照片并显示

本文最大优点在于适配Android8系统,项目给的平板版本很低,系统适配折磨了我很久
找了很多方法,这个版本是最简单并且可以成功运行的

0.AndroidMainfest.xml以及build.gradle配置文件

主要是添加权限uses-permission和provider,这些是必须添加的
provider根据自己的项目结构自行改,可以在后面写完file_paths.xml之后再写进来

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.buildmaterialapplication"><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"tools:ignore="ProtectedPermissions"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.CAMERA"/><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"><activityandroid:name=".MainActivity"android:exported="true"tools:ignore="DuplicateActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><providerandroid:authorities="com.buildmaterialapplication.fileprovider"android:name="androidx.core.content.FileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths"/></provider></application><supports-screens android:resizeable="true" />
</manifest>

build.gradle我不确定我有没有改过。。以防万一还是放上来

plugins {id 'com.android.application'
}android {compileSdk 31defaultConfig {applicationId "com.buildmaterialapplication"minSdk 19targetSdk 31versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'implementation 'androidx.constraintlayout:constraintlayout:2.0.4'implementation 'androidx.navigation:navigation-fragment:2.3.5'implementation 'androidx.navigation:navigation-ui:2.3.5'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'}

1.activity_main.xml页面

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ImageViewandroid:id="@+id/pic"android:layout_width="300dp"android:layout_height="500dp"android:layout_gravity="center"></ImageView>
</LinearLayout>

2.file_paths.xml相机拍摄照片存放位置

在res下建新文件夹xml在该文件夹下创建file_paths.xml,记得在Mainfest中写provider

本文使用了cache存储,若要使用其他存储需要对应修改xml文件中的路径

<?xml version="1.0" encoding="utf-8"?>
<resources><external-cache-path path="." name="take_photo"/>
</resources>

3.MainActivity.java

Android版本不同拍照获取图片的方式也不同
注意APP安装到手机上后设置权限,否则应用会闪退。本文中的askPermission函数会在打开应用时询问权限,一般不需要手动设置。

package com.buildmaterialapplication;import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;public class MainActivity extends AppCompatActivity {private static String[] items = new String[]{"拍照","从相册中选择",};public static final int TAKE_PHOTO=1;//声明一个请求码,用于识别返回的结果private static final int SCAN_OPEN_PHONE = 2;// 相册private Uri imageUri;public String path=null;Bitmap bitmap;public String picpath=null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);askPermission();choosePic();//aiAlgorithm}private void askPermission(){ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA},0);}private void choosePic(){AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this).setTitle("请选择图片")//设置对话框 标题.setItems(items, new DialogInterface.OnClickListener() {@RequiresApi(api = Build.VERSION_CODES.N)@Overridepublic void onClick(DialogInterface dialog, int which) {if(which==0){openCamera();}else{openGallery();}return;}});builder.create().show();}private void openGallery() {Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//intent.setType("image/*");startActivityForResult(intent, SCAN_OPEN_PHONE);}@RequiresApi(api = Build.VERSION_CODES.N)private void openCamera(){String imageName = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date());
//        File outputImage=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/data/com.example.woundapplication/"+imageName+".jpg");File outputImage = new File(getExternalCacheDir(), imageName+".jpg");Objects.requireNonNull(outputImage.getParentFile()).mkdirs();
//        Log.e("", outputImage.getAbsolutePath());/*创建一个File文件对象,用于存放摄像头拍下的图片,把它存放在应用关联缓存目录下,调用getExternalCacheDir()可以得到这个目录,为什么要用关联缓存目录呢?由于android6.0开始,读写sd卡列为了危险权限,使用的时候必须要有权限,应用关联目录则可以跳过这一步*/try//判断图片是否存在,存在则删除在创建,不存在则直接创建{if(outputImage.exists()){outputImage.delete();}boolean a = outputImage.createNewFile();Log.e("createNewFile", String.valueOf(a));}catch (IOException e){e.printStackTrace();}if(Build.VERSION.SDK_INT>=24)//判断安卓的版本是否高于7.0,高于则调用高于的方法,低于则调用低于的方法//把文件转换成Uri对象/*因为android7.0以后直接使用本地真实路径是不安全的,会抛出异常。FileProvider是一种特殊的内容提供器,可以对数据进行保护*/{imageUri= FileProvider.getUriForFile(MainActivity.this,"com.buildmaterialapplication.fileprovider",outputImage);//对应Mainfest中的provider
//            imageUri=Uri.fromFile(outputImage);path=imageUri.getPath();Log.e(">7:",path);}else {imageUri= Uri.fromFile(outputImage);path=imageUri.getPath();Log.e("<7:",imageUri.getPath());}//使用隐示的Intent,系统会找到与它对应的活动,即调用摄像头,并把它存储Intent intent0=new Intent("android.media.action.IMAGE_CAPTURE");intent0.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);startActivityForResult(intent0,TAKE_PHOTO);}@SuppressLint("SetTextI18n")protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);ImageView img_result=(ImageView) findViewById(R.id.pic);switch (requestCode) {case TAKE_PHOTO:if (resultCode == RESULT_OK) {//将图片解析成Bitmap对象,并把它显现出来
//                    String filePath = getFilesDir().getAbsolutePath()+"/image.jpeg";
//                    bitmap = BitmapFactory.decodeFile(filePath);//注意bitmap,后面再decode就会为空try {bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));} catch (FileNotFoundException e) {e.printStackTrace();}
//                        bitmap = BitmapFactory.decodeFile(picpath);picpath=imageUri.getPath().toString();Log.e("", imageUri.getAuthority());Log.e("picpath",picpath);@SuppressLint("SdCardPath") String fileName = picpath;img_result.setImageBitmap(bitmap);img_result.invalidate();}break;case SCAN_OPEN_PHONE:if (resultCode == RESULT_OK){Uri selectImage=data.getData();String[] FilePathColumn={MediaStore.Images.Media.DATA};Cursor cursor = getContentResolver().query(selectImage,FilePathColumn, null, null, null);cursor.moveToFirst();//从数据视图中获取已选择图片的路径int columnIndex = cursor.getColumnIndex(FilePathColumn[0]);picpath = cursor.getString(columnIndex);Log.e("picpath",picpath);cursor.close();bitmap = BitmapFactory.decodeFile(picpath);img_result.setImageBitmap(bitmap);img_result.invalidate();}break;default:break;}}}

4.手机调试方法

AS的虚拟机性能很差,个人都是用usb直接连手机调试的
步骤:

  1. 手机打开开发者模式中的usb调试
  2. usb连接电脑,选择传输文件/Android Auto
  3. 然后会提示什么usb调试授权之类的,给授权就可以了
  4. 运行这里出现手机型号就可以了
  5. 可能会出现testonly的bug,可以按我另一篇文章修改
    Error: INSTALL_FAILED_TEST_ONLY

AndroidStudio实现相机拍照或从相册中选取照片并显示相关推荐

  1. Android学习-运用手机多媒体-通知使用技巧、调用摄像头拍照、从相册中选取照片、播放音频和视频文件(MediaPlayer、VideoView)

    android提供了一系列的API,使得我们可以在程序中调用很多的多媒体资源,从而编写出更加丰富多彩的应用程序. 使用通知 通知(Notification)是Android系统中比较有特色的一个功能, ...

  2. 打开相机拍照或从相册中选择照片

    1.添加权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ...

  3. 调用Android系统自带相机拍照,从相册中获取图片

    一,前言: 在日常的手机应用开发过程中,经常会遇到上传图片的需求,像上传头像之类的,这就需要调用系统的相机,相册获取照片.但是在Android 系统7.0之后认为这种操作是不安全的,这篇文章主要就是记 ...

  4. Android拍照或从相册中取照片

    此文章只为记录本人在开发中遇到的坑以及学到的知识,里面可能还是存在问题,如果有问题希望大家能指出来,谢谢! 1.拍照 拍照需要适配7.0和7.0以下的手机,然后还需要申请相机和SD卡的读写权限.这次没 ...

  5. Android9上,调用系统相机拍照后,相册中不显示,第三方软件也读取不到

    一.问题:我的app调用系统拍照功能,然后使用知乎的Matisse框架加载自己定义的文件夹中的图片,发现怎么也不显示. 二.原因:Android给图片创建了一个数据库,我们需要手动去刷新这个数据库,把 ...

  6. android 从相册选择,Android开发从相册中选取照片

    最近项目在做一个功能:就是需要从用户选择头像跳转到相册选择图片,这应该是一个很简单的需求,但是在网上搜了一下有好多都讲的很乱,其实用几十行代码就可以实现的为什么要说的那么复杂呢,下面就简单说一下喽. ...

  7. Android相册中搜索功能,Android开发从相册中选取照片的示例代码

    最近项目在做一个功能:就是需要从用户选择头像跳转到相册选择图片,这应该是一个很简单的需求,但是在网上搜了一下有好多都讲的很乱,其实用几十行代码就可以实现的为什么要说的那么复杂呢,下面就简单说一下喽. ...

  8. android点击选择相册,android: 从相册中选择照片

    虽然调用摄像头拍照既方便又快捷,但并不是每一次我们都需要去当场拍一张照片的. 因为每个人的手机相册里应该都会存有许许多多张照片,直接从相册里选取一张现有的照 片会比打开相机拍一张照片更加常用.一个优秀 ...

  9. php拍照从手机相册中选择,微信js-sdk预览图片接口及从拍照或手机相册中选图接口用法示例...

    本文实例讲述了微信js-sdk预览图片接口及从拍照或手机相册中选图接口用法.分享给大家供大家参考,具体如下: 目前中js-sdk 1.0版本中,预览图片提供了2个接口,接口的定义参考官方文档 1.预览 ...

最新文章

  1. 老大说要自动化测试,我是怎么做的可以看看
  2. 干货篇:AI赋能医药工业发展案例
  3. sscanf函数中类型不匹配警告引发的BUG和思考
  4. python模拟用户压力测试_Python 工具 Locust 进行负载测试
  5. c++ vector方法
  6. 超赞!12套你没见过的社交媒体 社交网站图标
  7. 计算机系统的工作方式,某计算机系统输入/输出采用双缓冲工作方式,其工作过程如下图所示,假设磁盘块与缓冲 - 信管网...
  8. 【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器
  9. AFN的简单二次封装
  10. 吴恩达《机器学习》第一章:监督学习和无监督学习
  11. 微信小程序应用百度地图API
  12. 《CLR via C#》读书笔记-.NET多线程(一)
  13. go语言swag注解示例
  14. html打包成apk wex5,WeX5打包部署学习
  15. 如何制作朋友圈搞笑证件图片(附源码实例)
  16. 并查集巧妙用法(codeforces)C. Destroying Array
  17. Fluent NHibernate入门
  18. CTF Series Forensics
  19. 线性回归预时间序列预测
  20. 【NLP】Words Normalization+PorterStemmer源码解析

热门文章

  1. 驾考计算机播报原理,驾考科二电脑语音提示
  2. 计算压力倍增,携程度假起价引擎架构演变
  3. linux常用命令的英文单词缩写
  4. Openjudge-NOI题库-和数
  5. vba和宏_保留有关Excel公式和宏的注释
  6. SLAM算法评估中的轨迹拟合与外参求解
  7. 直播平台对企业的作用有哪些
  8. 安科瑞能耗系统在智能配电网下中小型企业(江阴市康乾车业有限公司)的设计和应用
  9. 洛谷 P1862 输油管道问题
  10. 第一章、华软代码生成器简单模板调制教程