zoukankan      html  css  js  c++  java
  • 调用摄像头拍照

    首先新建一个CameraAlbumTest项目。然后修改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">
    
        <Button
            android:id="@+id/take_photo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Take Phote"
            />
    
    
        <ImageView
            android:id="@+id/picture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            />
    
    </LinearLayout>

    定义完布局后,定义mainactivity

    package com.example.cameraalbumtest;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.content.FileProvider;
    
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    import android.provider.MediaStore;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class MainActivity extends AppCompatActivity {
    
        public static final int TAKE_PHOTO=1;
    
        private ImageView picture;
    
        private Uri imageUri;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //获取实例
            Button takePhoto=(Button) findViewById(R.id.take_photo);
            picture =(ImageView) findViewById(R.id.picture);
    
            takePhoto.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //创建file对象,用于存储拍照后的图片
                    File outputImage=new File(getExternalCacheDir(),"output_image.jpg");//把图片进行命名
                    //调用getExternalCacheDir()可以得到手机SD卡的应用关联缓存目录
                    //所谓的应用关联缓存目录,就是指SD卡中专门用于存放当前应用缓存数据的位置
                    //具体的路径是/sdcard/Android/data/<package name>/cache
    
                    //因为从Android 6.0系统开始,读写SD卡被列为了危险权限,
                    // 如果将图片存放在SD卡的任何其他目录,都要进行运行时权限处理才行,而使用应用关联目录则可以跳过这一步。
                    try {
                        if (outputImage.exists()) {//如果已经存在了图片,则删掉,
                            outputImage.delete();
                        }
                        outputImage.createNewFile();//将图片放入
                    }catch (IOException e){
                        e.printStackTrace();
                    }
    
                    //获取Uri对象
                    //这个Uri对象标识着output_image.jpg这张图片的本地真实路径。
                    if (Build.VERSION.SDK_INT >= 24) {
                        //调用FileProvider的getUriForFile() 方法将File 对象转换成一个封装过的Uri对象
                        imageUri = FileProvider.getUriForFile(MainActivity.this,"com.example.cameraalbumtest.fileprovider", outputImage);
                        //FileProvider则是一种特殊的内容提供器,它使用了和内容提供器类似的机制来对数据进行保护,
                        // 可以选择性地将封装过的Uri共享给外部,从而提高了应用的安全性。
                        //第一个参数要求传入Context 对象
                        //第二个参数可以是任意唯一的字符串 (需要在AndroidManifest.xml中声明)
                        //第三个参数则是我们刚刚创建的File 对象
    
                    } else {//若系统的版本低于Android7.0,则调用下面的方法将File对象转换为Uri对象
                        imageUri = Uri.fromFile(outputImage);
                    }
    
                    //启动相机程序
                    Intent intent= new Intent("android.media.action.IMAGE_CAPTURE");
                    intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);//指定图片的输出地址
                    startActivityForResult(intent,TAKE_PHOTO);//调用startActivityForResult() 来启动活动。
                }
            });
    
        }
    
        //使用startActivityForResult() 来启动活动的,
        // 因此拍完照后会有结果返回到onActivityResult() 方法中。
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            switch (requestCode) {
                case TAKE_PHOTO:
                    if (resultCode == RESULT_OK) {//如果拍照成功
                        try {
                            // 将拍摄的照片显示出来
                            //可以调用BitmapFactory的decodeStream() 方法将output_image.jpg这张照片解析成Bitmap 对象
                            Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                            picture.setImageBitmap(bitmap);//将Bitmap对象,设置到ImageView中显示出来。
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }

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

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.cameraalbumtest">
    
        <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">
    
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.example.cameraalbumtest.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>
    
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </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后有

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.cameraalbumtest">
    
        <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="androidx.core.content.FileProvider"
                android:authorities="***.fileProvider"
                android:exported="false"
                android:grantUriPermissions="true"
                xmlns:tools="http://schemas.android.com/tools"
                tools:replace="android:authorities">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>
    
    
        </application>
    
    </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>
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.cameraalbumtest">
    
        <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="androidx.core.content.FileProvider"
                android:authorities="com.example.cameraalbumtest.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true"
                xmlns:tools="http://schemas.android.com/tools"
                tools:replace="android:authorities">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>
    
    
        </application>
    
    </manifest>
  • 相关阅读:
    mysql 下 计算 两点 经纬度 之间的距离
    富爸爸财务自由之路
    Ubuntu16.04忘记MySQL5.7的root用户密码之解决方案
    Windowns下code: command not found
    Linux下CRMEB环境搭建
    PHP无法使用curl_init()函数
    请在mysql配置文件修sql-mode或sql_mode为NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    apache不能解析php之解决办法
    windows上hexo: command not found
    SyntaxError: Non-ASCII character 'æ' in file csdn.py on line 7, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
  • 原文地址:https://www.cnblogs.com/ltw222/p/14912415.html
Copyright © 2011-2022 走看看