Android 实现相机功能(完整源码)

Android 实现相机功能(完整源码)先上结果 图 1 图 2 图 3 activity main 布局代码 xmlversion 1 0 encoding utf 8 LinearLayout http schemas android com apk res android xmlns app http schemas android c android 相机开源代码

先上结果:

图1

在这里插入图片描述
图2:
在这里插入图片描述
图3:
在这里插入图片描述

activity_main 布局代码:

<?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"> <Button android:id="@+id/btn_photo" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:text="拍照"/> <ImageView android:id="@+id/img_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"/> </LinearLayout> 

MainActivity 代码

package ccv.turbosnail.photo_demo; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.provider.MediaStore; import android.support.annotation.Nullable; import android.support.v4.content.FileProvider; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class MainActivity extends AppCompatActivity { 
    public static final int TAKE_PHOTO =1; // TAKE_PHOTO来作为case处理图片的标识 private ImageView imgIcon; // 显示拍照后的图片 private Button btnPhoto; // 拍照 private Uri imageUri; // 通用资源标志符 @Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); //初始化控件 btnPhoto.setOnClickListener(new View.OnClickListener() { 
    @Override public void onClick(View v) { 
    / * 问: 首先为什么这里要创建时间对象? * 答: 因为,如果我们不用当前本地的时间作为图片的名字,当然这里图片的名字可以设为一个死值 * 例如:Monday.jpg — 那么对于这个死值作为图片的名字,当我们需要拍多张照片时,就会一直覆盖 * 这张照片,也就是说,我们就无法实现多张照片的保存,之前的照片就会被新的照片覆盖掉。 * 所以说,这里用本地的当前时间作为照片的名字,就解决了这个问题 * 简单的来说就是,利用本地时间 — 解决图片名冲突问题 */ SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); Date curDate = new Date(System.currentTimeMillis()); String str = format.format(curDate); / * 创建File对象,用于存储拍照后的照片 * 第一个参数: 是这张照片存放在手机SD卡的对应关联缓存应用 * 第二个参数: 这张图片的命名 */ File outputImage = new File(getExternalCacheDir(),str+".jpg"); try { 
    if (outputImage.exists()){ 
    // 检查与File对象相连接的文件和目录是否存在于磁盘中 outputImage.delete(); // 删除与File对象相连接的文件和目录 } outputImage.createNewFile(); // 如果与File对象相连接的文件不存在,则创建一个空文件 } catch (IOException e) { 
    e.printStackTrace(); } if (Build.VERSION.SDK_INT >= 24){ 
    // 如果运行设备的系统版本高于 Android7.0 / * 将File对象转换成一个封装过的Uri对象 * 第一个参数: 要求传入Context参数 * 第二个参数: 可以是任意唯一的字符串 * 第三个参数: 我们刚刚创建的File对象 */ imageUri = FileProvider.getUriForFile(MainActivity.this,"ccv.turbosnail.photo_demo.fileprovider",outputImage); }else{ 
    // 如果运行设备的系统版本低于 Android7.0 // 将File对象转换成Uri对象,这个Uri对象表示着 str + ".jpg" 这张图片的本地真实路径 imageUri = Uri.fromFile(outputImage); } / * 启动相机程序 */ // 将Intent的action指定为 拍照到指定目录 —— android.media.action.IMAGE_CAPTURE Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); // 指定图片的输出地址 intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri); / * 在通过startActivityForResult(),来启动活动,因此拍完照后会有结果返回到 onActivityResult()方法中 */ startActivityForResult(intent,TAKE_PHOTO); } }); } / * * @param requestCode 第一个是请求码,可以进行传递数据前的一些操作,比如根据不同的请求码,设置不同的传递内容。 * @param resultCode 第二个是返回码,也就是在B中设置的int的数值,这个是得到返回的内容的标识。 * @param data 第三个是Intent的数据,比如在B中的setResult方法中传递了一些数据,在A中就可以通过解析Intent的内容来获得传递过来的数据。 */ @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 
    switch (requestCode){ 
    case TAKE_PHOTO: if (resultCode == RESULT_OK){ 
    // 当拍照成功后,会返回一个返回码,这个值为 -1 — RESULT_OK try{ 
    // 根据Uri找到这张照片的资源位置,将它解析成Bitmap对象,然后将把它设置到imageView中显示出来 Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri)); imgIcon.setImageBitmap(bitmap); } catch (FileNotFoundException e) { 
    e.printStackTrace(); } } break; } } private void initView() { 
    btnPhoto = findViewById(R.id.btn_photo); imgIcon = findViewById(R.id.img_icon); } } 

AndroidManifest 代码:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ccv.turbosnail.photo_demo"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name="android.support.v4.content.FileProvider" android:authorities="ccv.turbosnail.photo_demo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> </manifest> 

接着:

在这里插入图片描述

最后,仔细看下注释,代码在上面,但是我还是希望大家能认真理解一下它们的意思

在这里插入图片描述

运行即可!

  1. 应用缓存目录:
    自从 Android6.0 系统开始,读写SD卡被列为了危险权限,如果将图片存放在SD卡的任何其他目录,都要进行运行时权限处理才行,而使用应用关联缓存目录可以跳过这一步 ,那么我们直接在创建File对象时,第一个参数填入 getExternalCacheDir()方法就可以得到这个目录
  2. 内容提供器的注册:
    自从 Android7.0系统开始,直接使用本地真实路径被认为是不安全的,会抛出一个FileUriExPosedException 异常,而FileProvider 是一种特殊的内容提供其,它使用了内容提供器类似的机制来对数据进行保护,可以选择性地将封装过的Uri 共享给外部,从而提高了应用的安全性。
  3. 版本问题:
    如果运行设备的系统版本低于 Android7.0,就调用Uri的 fromFile()方法将File 对象转换成Uri对象,这个对象标识着拍照的图片的本地真实路径。如果低于7.0版本,就调用FileProvider的getUriForFile() 方法将File对象转换成一个封装过的Uri 对象。

    最后感谢你们的收看,如果可以的话,给我一个赞和评论证明你们曾经来过,我会很欣慰的,你们支持这样用心的一位作者吗?

今天的文章 Android 实现相机功能(完整源码)分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-12-05 22:30
下一篇 2024-12-05 22:17

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/78498.html