Android---拍照

首先介绍下该程序能实现的功能(就是基本的两个):
1,调用手机相机进行拍照,然后返回给应用。
2,将拍好的照片保存到系统相册中。

讲讲有的没的,我这个是照着官方给的例子写的,但是过程中遇到一些问题。

先贴上代码把。首先是AndroidManifest.xml

AndroidManifest.xml

它需要添加的权限

    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

其次还需要添加一个内容提供者:
android:name这里很多网上的,包括开发文档都是v4包下的.但是我这边会出错,我就找到了这个

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

然后还需要一个xml文件:
官方文档中这里是external-files-path。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/cn.twle.android.opencvtest/files/Pictures" />
</paths>

主程序

先看下效果图
Android---拍照_第1张图片

Open Camera:

打开相机,进行拍照保存相片


    public void open(View view){
        dispatchTakePictureIntent();
    }

    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

            photoFile = null;

            try {
                photoFile = createImageFile();
            } catch (IOException ex) {

            }

            if (photoFile != null) {
                Uri uriForFile = FileProvider.getUriForFile(this,
                        "cn.twle.android.opencvtest.fileprovider",
                        photoFile);
                Uri photoURI = uriForFile;
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }
    }
    private File createImageFile() throws IOException {
        // Create an image file name
        //获得时间。yyyy(年),MM(月),dd(日),HH(小时),mm(分),ss(秒)。
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        //进行图片名称进行拼接
        imageFileName = "JPEG_" + timeStamp + "_";

        //获得该应用包下文件的Pictures目录(如果没有会自动创建)
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        //创建image文件
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        //获取图片的绝对路径+图片名
        currentPhotoPath = image.getAbsolutePath();
        Log.e("TAG---------------",currentPhotoPath+"");
        return image;
    }

Save:

在官方文档中用的是利用广播来进行图片保存,但是我试了一下,我没有成功就改用了下面的方法

 //保存照片到相册
    public void save(View view){
        if(currentPhotoPath==null)//如果该图片文件为空
            return;
        try {
            Log.e("TAG","yes");
            MediaStore.Images.Media.insertImage(getContentResolver(), currentPhotoPath, photoFile.getName(), photoFile.getName());
        } catch (FileNotFoundException e) {
            Log.e("TAG","no");
            e.printStackTrace();
        }
    }

回调方法:

    //打开相机后返回该程序,会回调这个方法
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //如果相机有拍照resultCode会返回1,如果没有则返回0。如果手机成功打开相机,则requestCode会返回1,否则返回0
        Log.e("onActivityResult:",requestCode+"----"+resultCode+"--------"+data+"");

        //如果没拍照怎么把文件删除。不然会留下一个0bit的空白文件
        if(resultCode==0){
            photoFile.delete();
            currentPhotoPath=null;
            return;
        }

        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            //这里不是很明白,为什么明明有拍照,但是data是返回null...(有时间再探究)
            if(data==null){
                image_main.setImageURI(Uri.fromFile(photoFile));
            }else {
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                image_main.setImageBitmap(imageBitmap);
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

拍照后的照片会保存在Android/data/packageName/files/Pictures目录下


完整程序

/*
    创建一个文件。prefix:前缀;suffix:后缀;directory:目录
    File.createTempFile(prefix ,suffix ,directory)
 */
public class MainActivity extends AppCompatActivity {

    private ImageView image_main;

    static final int REQUEST_IMAGE_CAPTURE = 1;
    static final int REQUEST_TAKE_PHOTO = 1;

    String currentPhotoPath;    //图片的绝对路径
    File photoFile;             //操作时将创建个文件
    String imageFileName;       //该图片名称

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setupOpenCV();
        initView();
    }

    private void initView() {
        image_main=findViewById(R.id.image_main);
    }

    private void setupOpenCV() {

        boolean mInitSuccess = OpenCVLoader.initDebug();
        if (mInitSuccess) {
            Log.e("TAG", "OpenCV init success");
        } else {
            Log.e("TAG", "OpenCV init failed");
        }
    }


    public void open(View view){
        dispatchTakePictureIntent();
    }

    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

            photoFile = null;

            try {
                photoFile = createImageFile();
            } catch (IOException ex) {

            }

            if (photoFile != null) {
                Uri uriForFile = FileProvider.getUriForFile(this,
                        "cn.twle.android.opencvtest.fileprovider",
                        photoFile);
                Uri photoURI = uriForFile;
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }
    }
    private File createImageFile() throws IOException {
        // Create an image file name
        //获得时间。yyyy(年),MM(月),dd(日),HH(小时),mm(分),ss(秒)。
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        //进行图片名称进行拼接
        imageFileName = "JPEG_" + timeStamp + "_";

        //获得该应用包下文件的Pictures目录(如果没有会自动创建)
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        //创建image文件
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        //获取图片的绝对路径+图片名
        currentPhotoPath = image.getAbsolutePath();
        Log.e("TAG---------------",currentPhotoPath+"");
        return image;
    }

    //打开相机后返回该程序,会回调这个方法
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //如果相机有拍照resultCode会返回1,如果没有则返回0。如果手机成功打开相机,则requestCode会返回1,否则返回0
        Log.e("onActivityResult:",requestCode+"----"+resultCode+"--------"+data+"");

        //如果没拍照怎么把文件删除。不然会留下一个0bit的空白文件
        if(resultCode==0){
            photoFile.delete();
            currentPhotoPath=null;
            return;
        }

        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            //这里不是很明白,为什么明明有拍照,但是data是返回null...(有时间再探究)
            if(data==null){
                image_main.setImageURI(Uri.fromFile(photoFile));
            }else {
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                image_main.setImageBitmap(imageBitmap);
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    //保存照片到相册
    public void save(View view){
        if(currentPhotoPath==null)//如果该图片文件为空
            return;
        try {
            Log.e("TAG","yes");
            MediaStore.Images.Media.insertImage(getContentResolver(), currentPhotoPath, photoFile.getName(), photoFile.getName());
        } catch (FileNotFoundException e) {
            Log.e("TAG","no");
            e.printStackTrace();
        }
    }

        //-----------获取的应用权限------------------------------
//    public void one(View v) {
//        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1);
//        }
//    }
//    public void two(View v)  {
//        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
//            ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},2);
//        }
//
//    }
//    public void three(View v)  {
//        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
//            ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},3);
//        }
//    }
}

你可能感兴趣的:(#,Android2)