zoukankan      html  css  js  c++  java
  • Android学习——调用摄像头拍照

    首先新建一个CameraAlbumTest项目。然后修改activity_main.xml中的代码,如下所示:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:app="http://schemas.android.com/apk/res-auto"
     4     xmlns:tools="http://schemas.android.com/tools"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     android:orientation="vertical"
     8     tools:context=".MainActivity">
     9  
    10     <Button
    11         android:id="@+id/take_photo"
    12         android:layout_width="match_parent"
    13         android:layout_height="wrap_content"
    14         android:text="Take Phote"
    15         />
    16  
    17  
    18     <ImageView
    19         android:id="@+id/picture"
    20         android:layout_width="wrap_content"
    21         android:layout_height="wrap_content"
    22         android:layout_gravity="center_horizontal"
    23         />
    24  
    25 </LinearLayout>

    定义完布局后,定义mainactivity

      1 package com.example.cameraalbumtest;
      2  
      3 import androidx.appcompat.app.AppCompatActivity;
      4 import androidx.core.content.FileProvider;
      5  
      6 import android.content.Intent;
      7 import android.graphics.Bitmap;
      8 import android.graphics.BitmapFactory;
      9 import android.net.Uri;
     10 import android.os.Build;
     11 import android.os.Bundle;
     12 import android.provider.MediaStore;
     13 import android.view.View;
     14 import android.widget.Button;
     15 import android.widget.ImageView;
     16  
     17 import java.io.File;
     18 import java.io.FileNotFoundException;
     19 import java.io.IOException;
     20  
     21 public class MainActivity extends AppCompatActivity {
     22  
     23     public static final int TAKE_PHOTO=1;
     24  
     25     private ImageView picture;
     26  
     27     private Uri imageUri;
     28  
     29     @Override
     30     protected void onCreate(Bundle savedInstanceState) {
     31         super.onCreate(savedInstanceState);
     32         setContentView(R.layout.activity_main);
     33  
     34         //获取实例
     35         Button takePhoto=(Button) findViewById(R.id.take_photo);
     36         picture =(ImageView) findViewById(R.id.picture);
     37  
     38         takePhoto.setOnClickListener(new View.OnClickListener() {
     39             @Override
     40             public void onClick(View v) {
     41                 //创建file对象,用于存储拍照后的图片
     42                 File outputImage=new File(getExternalCacheDir(),"output_image.jpg");//把图片进行命名
     43                 //调用getExternalCacheDir()可以得到手机SD卡的应用关联缓存目录
     44                 //所谓的应用关联缓存目录,就是指SD卡中专门用于存放当前应用缓存数据的位置
     45                 //具体的路径是/sdcard/Android/data/<package name>/cache
     46  
     47                 //因为从Android 6.0系统开始,读写SD卡被列为了危险权限,
     48                 // 如果将图片存放在SD卡的任何其他目录,都要进行运行时权限处理才行,而使用应用关联目录则可以跳过这一步。
     49                 try {
     50                     if (outputImage.exists()) {//如果已经存在了图片,则删掉,
     51                         outputImage.delete();
     52                     }
     53                     outputImage.createNewFile();//将图片放入
     54                 }catch (IOException e){
     55                     e.printStackTrace();
     56                 }
     57  
     58                 //获取Uri对象
     59                 //这个Uri对象标识着output_image.jpg这张图片的本地真实路径。
     60                 if (Build.VERSION.SDK_INT >= 24) {
     61                     //调用FileProvider的getUriForFile() 方法将File 对象转换成一个封装过的Uri对象
     62                     imageUri = FileProvider.getUriForFile(MainActivity.this,"com.example.cameraalbumtest.fileprovider", outputImage);
     63                     //FileProvider则是一种特殊的内容提供器,它使用了和内容提供器类似的机制来对数据进行保护,
     64                     // 可以选择性地将封装过的Uri共享给外部,从而提高了应用的安全性。
     65                     //第一个参数要求传入Context 对象
     66                     //第二个参数可以是任意唯一的字符串 (需要在AndroidManifest.xml中声明)
     67                     //第三个参数则是我们刚刚创建的File 对象
     68  
     69                 } else {//若系统的版本低于Android7.0,则调用下面的方法将File对象转换为Uri对象
     70                     imageUri = Uri.fromFile(outputImage);
     71                 }
     72  
     73                 //启动相机程序
     74                 Intent intent= new Intent("android.media.action.IMAGE_CAPTURE");
     75                 intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);//指定图片的输出地址
     76                 startActivityForResult(intent,TAKE_PHOTO);//调用startActivityForResult() 来启动活动。
     77             }
     78         });
     79  
     80     }
     81  
     82     //使用startActivityForResult() 来启动活动的,
     83     // 因此拍完照后会有结果返回到onActivityResult() 方法中。
     84     @Override
     85     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     86         super.onActivityResult(requestCode, resultCode, data);
     87         switch (requestCode) {
     88             case TAKE_PHOTO:
     89                 if (resultCode == RESULT_OK) {//如果拍照成功
     90                     try {
     91                         // 将拍摄的照片显示出来
     92                         //可以调用BitmapFactory的decodeStream() 方法将output_image.jpg这张照片解析成Bitmap 对象
     93                         Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
     94                         picture.setImageBitmap(bitmap);//将Bitmap对象,设置到ImageView中显示出来。
     95                     } catch (FileNotFoundException e) {
     96                         e.printStackTrace();
     97                     }
     98                 }
     99                 break;
    100             default:
    101                 break;
    102         }
    103     }
    104 }

    由于采用到了内容提供器(FileProvider),那么我们自然要在AndroidManifest.xml中对内容提供器进行注册了,如下所示:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.example.cameraalbumtest">
     4  
     5     <application
     6         android:allowBackup="true"
     7         android:icon="@mipmap/ic_launcher"
     8         android:label="@string/app_name"
     9         android:roundIcon="@mipmap/ic_launcher_round"
    10         android:supportsRtl="true"
    11         android:theme="@style/AppTheme">
    12  
    13         <provider
    14             android:name="android.support.v4.content.FileProvider"
    15             android:authorities="com.example.cameraalbumtest.fileprovider"
    16             android:exported="false"
    17             android:grantUriPermissions="true">
    18             <meta-data
    19                 android:name="android.support.FILE_PROVIDER_PATHS"
    20                 android:resource="@xml/file_paths" />
    21         </provider>
    22  
    23         <activity android:name=".MainActivity">
    24             <intent-filter>
    25                 <action android:name="android.intent.action.MAIN" />
    26  
    27                 <category android:name="android.intent.category.LAUNCHER" />
    28             </intent-filter>
    29         </activity>
    30     </application>
    31  
    32 </manifest>

    其中,android:name 属性的值是固定的,android:authorities 属性的值必须要和刚才FileProvider.getUriForFile() 方法中的第二个参数一致。另外,这里还在<provider> 标签的内部使用<meta-data> 来指定Uri 的共享路径,并引用了一个@xml/file_paths 资源。当然,这个资源现在还是不存在的,下面我们就来创建它。
    右击res 目录→New→Directory,创建一个xml目录,接着右击xml目录→New→File,创建一个file_paths.xml文件。然后修改file_paths.xml文件中的内容,如下所示:

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <paths xmlns:android="http://schemas.android.com/apk/res/android">
    3     <external-path name="my_images" path="" />
    4 </paths>

    其中,external-path 就是用来指定Uri 共享的,name 属性的值可以随便填,path 属性的值表示共享的具体路径。这里设置空值就表示将整个SD卡进行共享。

    同时声明一下访问SD卡的权限

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

    运行会发现报错。感觉第一行代码里面的程序的版本还是有点低哎。比如这里,必须填路径,但是里面就说空都可以。修改AndroidManifest.xml中的fileprovider后有

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.example.cameraalbumtest">
     4  
     5     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     6  
     7     <application
     8         android:allowBackup="true"
     9         android:icon="@mipmap/ic_launcher"
    10         android:label="@string/app_name"
    11         android:roundIcon="@mipmap/ic_launcher_round"
    12         android:supportsRtl="true"
    13         android:theme="@style/AppTheme">
    14  
    15         <activity android:name=".MainActivity">
    16             <intent-filter>
    17                 <action android:name="android.intent.action.MAIN" />
    18  
    19                 <category android:name="android.intent.category.LAUNCHER" />
    20             </intent-filter>
    21         </activity>
    22  
    23         <provider
    24             android:name="androidx.core.content.FileProvider"
    25             android:authorities="***.fileProvider"
    26             android:exported="false"
    27             android:grantUriPermissions="true"
    28             xmlns:tools="http://schemas.android.com/tools"
    29             tools:replace="android:authorities">
    30             <meta-data
    31                 android:name="android.support.FILE_PROVIDER_PATHS"
    32                 android:resource="@xml/file_paths" />
    33         </provider>
    34  
    35  
    36     </application>
    37  
    38 </manifest>

    再修改

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <paths xmlns:android="http://schemas.android.com/apk/res/android">
    3     <external-path name="my_images" path="/" />
    4 </paths>
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.example.cameraalbumtest">
     4  
     5     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     6  
     7     <application
     8         android:allowBackup="true"
     9         android:icon="@mipmap/ic_launcher"
    10         android:label="@string/app_name"
    11         android:roundIcon="@mipmap/ic_launcher_round"
    12         android:supportsRtl="true"
    13         android:theme="@style/AppTheme">
    14  
    15         <activity android:name=".MainActivity">
    16             <intent-filter>
    17                 <action android:name="android.intent.action.MAIN" />
    18  
    19                 <category android:name="android.intent.category.LAUNCHER" />
    20             </intent-filter>
    21         </activity>
    22  
    23         <provider
    24             android:name="androidx.core.content.FileProvider"
    25             android:authorities="com.example.cameraalbumtest.fileprovider"
    26             android:exported="false"
    27             android:grantUriPermissions="true"
    28             xmlns:tools="http://schemas.android.com/tools"
    29             tools:replace="android:authorities">
    30             <meta-data
    31                 android:name="android.support.FILE_PROVIDER_PATHS"
    32                 android:resource="@xml/file_paths" />
    33         </provider>
    34  
    35  
    36     </application>
    37  
    38 </manifest>
  • 相关阅读:
    Java的异常类的整理
    java中tostring的重载
    java中的引用于c++的指针的相互代替(就以创建简单的栈去讲解)
    Java版单词搜索
    Java/C++的正则表达式的总结归纳
    某个整数的全排列问题
    DFS+单词搜索
    一维数组组合
    离线升级OpenSSH详细步骤 ——安全漏洞修复(实战篇 Centos 6.5/6.10 操作系统)
    Mysql子查询
  • 原文地址:https://www.cnblogs.com/znjy/p/14908506.html
Copyright © 2011-2022 走看看