一、请求相机功能

声明你的应用依赖于相机,请在清单文件中添加 uses-feature 代码:

<manifest ... ><uses-feature android:name="android.hardware.camera"android:required="true" />...
</manifest>

如果你的应用使用相机,但不需要相机也可以正常运作,应将 android:required 设为 false.

你必须负责通过调用 hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) 检查相机在运行时的可用性。如果相机不可用,您应停用相机功能。

二、使用相机应用拍照

Android 向其他应用委托操作的方法是调用一个 Intent,用于描述要执行的操作。此过程涉及三个部分:Intent 本身,用于启动外部 Activity 的调用,以及用于在焦点返回到 Activity 时处理图片数据的一些代码。

 static final int REQUEST_IMAGE_CAPTURE = 1;private void dispatchTakePictureIntent() {Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (takePictureIntent.resolveActivity(getPackageManager()) != null) {startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);}}

三、获取缩略图

Android 相机应用会对返回 Intent(作为 extra 中的小型 Bitmap 传递给 onActivityResult(),使用键 “data”)中的照片进行编码。下面的代码会获取此图片,并将其显示在一个 ImageView 中。

if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {// Android 相机应用会对返回 Intent(作为 extra 中的小型 Bitmap 传递给 onActivityResult(),使用键 "data")中的照片进行编码assert data != null;Bundle extras = data.getExtras();// 获取缩略图Bitmap imageBitmap = (Bitmap) extras.get("data");imageView.setImageBitmap(imageBitmap);
}

四、保存完整尺寸的照片

Android 相机应用会保存一张完整尺寸的照片,前提是你为该照片指定了一个文件来保存它。你必须为相机应用应保存照片的位置提供一个完全限定的文件名称。

通常情况下,用户使用设备相机拍摄的所有照片都应保存在设备的公共外部存储设备中,以供所有应用访问。合适的共享照片目录由具有 DIRECTORY_PICTURES 参数的 getExternalStoragePublicDirectory() 提供。由于这种方法提供的目录会在所有应用之间共享,因此对该目录执行读写操作分别需要 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限。拥有写入权限即暗示可以读取,因此,如果你需要写入到外部存储设备,就只需请求一个权限:

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

不过,如果希望这些照片仍仅对你的应用保持私密状态,可以改用 getExternalFilesDir() 提供的目录。在 Android 4.3 及更低版本中,向此目录写入还需要 WRITE_EXTERNAL_STORAGE 权限。从 Android 4.4 开始不再需要此权限,因为其他应用无法访问该目录,因此可以通过添加 maxSdkVersion 属性来声明应仅在较低版本的 Android 上请求此权限:

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

注意:用户卸载你的应用后,你在 getExternalFilesDir() 或 getFilesDir() 提供的目录中保存的文件会被删除。

确定文件目录后,你需要指定一个不会跟其他文件产生冲突的文件名。你还可以将该路径保存在成员变量中以供日后使用。

    String currentPhotoPath;/*** 创建保存照片的文件* @return 创建好的文件* @throws IOException*/private File createImageFile() throws IOException {String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());String imageFileName = "JPEG_" + timeStamp + "_";// 仅对自己的应用保持私密状态,私有目录,用户卸载应用后,该目录中保存的文件会被删除。File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);File image = File.createTempFile(imageFileName, ".jpg", storageDir);// Save a file: path for use with ACTION_VIEW intentscurrentPhotoPath = image.getAbsolutePath();return  image;}

使用这种方法为照片创建文件后,你现在可以创建和调用 Intent,如下所示:

 static final int REQUEST_TAKE_PHOTO = 1;/*** 调起相机,并保存拍照后的原始图片*/private void dispatchTakePictureIntent2() {if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {Log.d("yanis", "没有相机");return;}Log.d("yanis", "有相机");Intent takePictureIntent  = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 如果可以调起相机if (takePictureIntent.resolveActivity(getPackageManager()) != null) {File photoFile = null;try {photoFile = createImageFile();} catch (IOException e) {e.printStackTrace();}if (photoFile != null) {Uri photoURI = FileProvider.getUriForFile(this, "com.yanis.androidexample.fileprovider", photoFile);takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);}}}

注意:这里使用的是 getUriForFile(Context, String, File),它会返回 content:// URI。对于以 Android 7.0(API 级别 24)及更高版本为目标平台的最新应用,跨越软件包边界传递 file:// URI 会导致出现 FileUriExposedException。

现在,你需要配置 FileProvider。在应用清单中,向你的应用添加提供器:

 <application>...<providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.yanis.androidexample.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider>...</application>

确保授权字符串与 getUriForFile(Context, String, File) 的第二个参数匹配。另外Provider需要在专用资源文件 res/xml/file_paths.xml 中配置符合条件的路径。

<?xml version="1.0" encoding="utf-8"?>
<paths><external-pathname="external"path="." /><external-files-pathname="external_files"path="." /><cache-pathname="cache"path="." /><external-cache-pathname="external_cache"path="." /><files-pathname="files"path="." />
</paths>

五、将照片添加到图库

对于所有其他人而言,为了让你的照片可供访问,最简单的方式可能是让其可从系统的媒体提供商访问。
注意:如果你将照片保存到 getExternalFilesDir() 提供的目录中,媒体扫描器将无法访问相应的文件,因为这些文件对您的应用保持私密状态。

下面的示例方法演示了如何调用系统的媒体扫描器以将你的照片添加到媒体Provider的数据库中,使 Android 图库应用中显示这些照片并使它们可供其他应用使用。

 /*** 将拍照的原始照片保存到图库*/private void galleryAddPic() {File f = new File(currentPhotoPath);Uri contentUri = Uri.fromFile(f);try {MediaStore.Images.Media.insertImage(getContentResolver(), currentPhotoPath, f.getName(), null);} catch (FileNotFoundException e) {e.printStackTrace();}this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, contentUri));}

六、对调整后的图片进行解码

如果内存有限,管理多张完整尺寸的图片可能会比较棘手。如果你发现应用仅显示几张图片就内存不足,则可以将 JPEG 扩展到内存数组(已调整为与目标视图的大小匹配),从而大幅减少动态堆的使用量。下面的示例方法演示了这种方法。

 /*** 将原始图片缩放后设置到目标控件上*/private void setPic() {// Get the dimensions of the Viewint targetW = imageView.getWidth();int targetH = imageView.getHeight();Log.d("yanis", "targetW = " + targetW);Log.d("yanis", "targetH = " + targetH);// Get the dimensions of the bitmapBitmapFactory.Options bmOptions = new BitmapFactory.Options();bmOptions.inJustDecodeBounds = true;// 获取原始图片尺寸信息,不实际加载图片到内存,所以这里的bitmap为nullBitmap bitmapSize = BitmapFactory.decodeFile(currentPhotoPath, bmOptions);Log.d("yanis", "bitmapSize = " + bitmapSize);int photoW = bmOptions.outWidth;int photoH = bmOptions.outHeight;Log.d("yanis", "photoW = " + photoW);Log.d("yanis", "photoH = " + photoH);// Determine how much to scale down the imageint scaleFactor = Math.min(photoW/targetW, photoH/targetH);Log.d("yanis", "scaleFactor = " + scaleFactor);// Decode the image file into a Bitmap sized to fill the ViewbmOptions.inJustDecodeBounds = false;bmOptions.inSampleSize = scaleFactor;bmOptions.inPurgeable = true;Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath, bmOptions);Log.d("yanis", "压缩后 = " + bitmap.getWidth());Log.d("yanis", "压缩后 = " + bitmap.getHeight());imageView.setImageBitmap(bitmap);}

最后看一下app module下的build.gradle文件的内容

plugins {id 'com.android.application'
}android {compileSdkVersion 29buildToolsVersion "29.0.3"defaultConfig {applicationId "com.yanis.androidexample"minSdkVersion 16targetSdkVersion 29versionCode 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.1.0'implementation 'com.google.android.material:material:1.1.0'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.1'androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

Android调用系统相机程序相关推荐

  1. android系统应用程序,Android调用系统应用程序

    Android调用系统应用程序: 1.直接拨打电话: Intent callIntent = new Intent(Intent.ACTION_CALL, Uri .parse("tel:1 ...

  2. Android调用系统相机拍照并保存到指定位置

    Android调用系统相机拍照并保存到指定位置 @Click(R.id.btn_takePhoto)void onclick() {Intent intent = new Intent(MediaSt ...

  3. android固定位置拍照,Android调用系统相机拍照并保存到指定位置

    Android调用系统相机拍照并保存到指定位置 @Click(R.id.btn_takePhoto) void onclick() { Intent intent = new Intent(Media ...

  4. android 调用系统相机拍照 获取原图

    博客源址:android 调用系统相机拍照 获取原图 博客时间:2013-04-23 11:08 好吧,为了这个问题又折腾了一整天.之前在网上找来的方法,如果在onActivityResult中直接用 ...

  5. Android调用系统相机拍照

    参考: Taking Photos Simply FileProvider 项目地址(好多人找我要,我传到百度云啦,大家自取):链接:https://pan.baidu.com/s/1nWsoE0eS ...

  6. Android调用系统相机和相册(更换微信头像)

    最近做了调用系统相机和相册,在其他博客中看到还有对图像进行剪切,大家都知道,我们在玩微信的时候,头像更换是方形图片,接下来我们就对这种情况具体进行描述: 必要的权限: <uses-permiss ...

  7. android调用系统相机返回图片模糊

    最近需要用到调用系统相机拍摄照片的功能,于是就直接调用系统的相机进行拍照,发现返回的bitmap存储之后都是非常模糊的 调用系统相机拍摄照片,由于StartActivityForResult过时,改用 ...

  8. android 实现自动拍照,Android:调用系统相机实现拍照+裁切(兼容7.0以上系统)

    android.jpg 前言 在平时的工作中,我们会经常遇到这样的需求:比如更改用户头像,我们就需要打开相机或相册,选择照片后进行裁剪,最后上传给后台... 相信这样的功能对小伙伴们来说可能早已司空见 ...

  9. android异常相机处理,android 调用系统相机拍照的各种异常处理

    1 本文只讨论调用系统相机出现的异常解决办法下面是调用系统相机的代码 先看一下最简单的写法 Intent intent = new Intent(android.provider.MediaStore ...

最新文章

  1. 虚拟机的联网模式正确的选择
  2. python 编程一日一练-python每日一练
  3. spring源码分析之@ImportSelector、@Import、ImportResource工作原理分析
  4. 二、Netty服务端/客户端启动整体流程
  5. 【thymeleaf】分页代码
  6. C 语言和C++语言的 struct对比
  7. Java封装图书信息类
  8. php 编译 iconv错误,php编译错误:configure: error: Please reinstall the iconv library.
  9. STM32工作笔记002---STM32初探-概述
  10. 关于 动态分流系统 ABTestingGateway 的想法
  11. 田申:《个人信息安全规范》的理解与初探
  12. matlab中readfid函数,matlab中textscan和textread函数的比较使用
  13. 软件研发成本构成中的间接成本包括哪些?
  14. 为什么要在信号线上串联一些小电阻
  15. Python获取图片保存对应的文件夹
  16. 读白帽子讲WEB安全,摘要
  17. 生产系统规划仿真软件
  18. 求简单多边形面积时非常有用的“鞋带公式”
  19. STM32(C语言)内存分布
  20. javaer的目标,是星辰大海!

热门文章

  1. 网页调用exe程序(写注册表)
  2. Cannot create table [data_source]: 1118 - Row size too large. The maximum row size for the used tabl
  3. Java实现小型英汉互译服务器
  4. C#用于网络通信时预先判断到指定IP是否畅通方法
  5. 0x0000000A 蓝屏问题
  6. js时间戳转日期封装调用
  7. 解决三星手机拍照后裁剪图片时横屏问题
  8. 哈工大操作系统实验一——操作系统的引导
  9. 如何几行代码看到网恋对象的原型
  10. Tomcat类加载机制与JVM类加载机制对比