AndroidStudio实现相机拍照或从相册中选取照片并显示
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直接连手机调试的
步骤:
- 手机打开开发者模式中的usb调试
- usb连接电脑,选择传输文件/Android Auto
- 然后会提示什么usb调试授权之类的,给授权就可以了
- 运行这里出现手机型号就可以了
- 可能会出现testonly的bug,可以按我另一篇文章修改
Error: INSTALL_FAILED_TEST_ONLY
AndroidStudio实现相机拍照或从相册中选取照片并显示相关推荐
- Android学习-运用手机多媒体-通知使用技巧、调用摄像头拍照、从相册中选取照片、播放音频和视频文件(MediaPlayer、VideoView)
android提供了一系列的API,使得我们可以在程序中调用很多的多媒体资源,从而编写出更加丰富多彩的应用程序. 使用通知 通知(Notification)是Android系统中比较有特色的一个功能, ...
- 打开相机拍照或从相册中选择照片
1.添加权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ...
- 调用Android系统自带相机拍照,从相册中获取图片
一,前言: 在日常的手机应用开发过程中,经常会遇到上传图片的需求,像上传头像之类的,这就需要调用系统的相机,相册获取照片.但是在Android 系统7.0之后认为这种操作是不安全的,这篇文章主要就是记 ...
- Android拍照或从相册中取照片
此文章只为记录本人在开发中遇到的坑以及学到的知识,里面可能还是存在问题,如果有问题希望大家能指出来,谢谢! 1.拍照 拍照需要适配7.0和7.0以下的手机,然后还需要申请相机和SD卡的读写权限.这次没 ...
- Android9上,调用系统相机拍照后,相册中不显示,第三方软件也读取不到
一.问题:我的app调用系统拍照功能,然后使用知乎的Matisse框架加载自己定义的文件夹中的图片,发现怎么也不显示. 二.原因:Android给图片创建了一个数据库,我们需要手动去刷新这个数据库,把 ...
- android 从相册选择,Android开发从相册中选取照片
最近项目在做一个功能:就是需要从用户选择头像跳转到相册选择图片,这应该是一个很简单的需求,但是在网上搜了一下有好多都讲的很乱,其实用几十行代码就可以实现的为什么要说的那么复杂呢,下面就简单说一下喽. ...
- Android相册中搜索功能,Android开发从相册中选取照片的示例代码
最近项目在做一个功能:就是需要从用户选择头像跳转到相册选择图片,这应该是一个很简单的需求,但是在网上搜了一下有好多都讲的很乱,其实用几十行代码就可以实现的为什么要说的那么复杂呢,下面就简单说一下喽. ...
- android点击选择相册,android: 从相册中选择照片
虽然调用摄像头拍照既方便又快捷,但并不是每一次我们都需要去当场拍一张照片的. 因为每个人的手机相册里应该都会存有许许多多张照片,直接从相册里选取一张现有的照 片会比打开相机拍一张照片更加常用.一个优秀 ...
- php拍照从手机相册中选择,微信js-sdk预览图片接口及从拍照或手机相册中选图接口用法示例...
本文实例讲述了微信js-sdk预览图片接口及从拍照或手机相册中选图接口用法.分享给大家供大家参考,具体如下: 目前中js-sdk 1.0版本中,预览图片提供了2个接口,接口的定义参考官方文档 1.预览 ...
最新文章
- 老大说要自动化测试,我是怎么做的可以看看
- 干货篇:AI赋能医药工业发展案例
- sscanf函数中类型不匹配警告引发的BUG和思考
- python模拟用户压力测试_Python 工具 Locust 进行负载测试
- c++ vector方法
- 超赞!12套你没见过的社交媒体 社交网站图标
- 计算机系统的工作方式,某计算机系统输入/输出采用双缓冲工作方式,其工作过程如下图所示,假设磁盘块与缓冲 - 信管网...
- 【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器
- AFN的简单二次封装
- 吴恩达《机器学习》第一章:监督学习和无监督学习
- 微信小程序应用百度地图API
- 《CLR via C#》读书笔记-.NET多线程(一)
- go语言swag注解示例
- html打包成apk wex5,WeX5打包部署学习
- 如何制作朋友圈搞笑证件图片(附源码实例)
- 并查集巧妙用法(codeforces)C. Destroying Array
- Fluent NHibernate入门
- CTF Series Forensics
- 线性回归预时间序列预测
- 【NLP】Words Normalization+PorterStemmer源码解析