Android-----调用系统相机拍照并把照片展示在图库中

此博客主要实现调用系统相机拍照,并把图片保存到指定目录下,更新数媒库将图片在图库中显示,布局xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:background="@drawable/back_1"
    tools:context="com.org.youtu.MainActivity">


    <Button
            android:id="@+id/btn_photo"
            android:layout_width="80dp"
            android:layout_height="60dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:background="@drawable/image"
            android:layout_marginBottom="30sp"/>


</LinearLayout>

逻辑处理代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button takePhoto;

    private Uri imageUri;//图片路径
    private String filename;//图片名称


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        requestPermissions();   //权限申请

        takePhoto = this.findViewById(R.id.btn_photo);
        takePhoto.setOnClickListener(this);

     

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_photo:
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //照相
                startActivityForResult(intent,1008);    //启动照相
                break;
          
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode,resultCode,data);
        if (resultCode != RESULT_OK){
            Toast.makeText(MainActivity.this, "ActivityResult返回码错误!", Toast.LENGTH_SHORT).show();
            return;
        }
        switch (requestCode){
            case 1008:

                saveCameraImage(data);
                break;
        }
    }


    /**【申请手机相机和内存读取权限】**/
    public void requestPermissions(){
        String [] permissions = new String[] {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO,
        };
        ActivityCompat.requestPermissions(MainActivity.this,permissions,100);
    }



    /**【保存相机拍的图片】**/
    public void saveCameraImage(Intent data){

        String path = Environment.getExternalStorageDirectory().toString() + "/DCIM/youtu/";
        File newFolder = new File(path);
        if (!newFolder.exists()){
            boolean isfal = newFolder.mkdirs();
            Log.e("isfal","创建目录:"+path+"<-状态->" + isfal);
        }
        Log.e("path","路径:"+path);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date(System.currentTimeMillis());
        filename = format.format(date);
        File outputImage = new File(newFolder,filename+".jpg");
        FileOutputStream out = null;
        BufferedOutputStream bos = null;
        try {
            out = new FileOutputStream(outputImage);
            bos = new BufferedOutputStream(out);
            Bitmap bitmap = (Bitmap) data.getExtras().get("data");// 解析返回的图片成bitmap
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);
            /**【通知媒体库更新数据库,在图库中能看到图片】**/
            MediaStore.Images.Media.insertImage(getContentResolver(),bitmap,null,null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                bos.flush();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

不要忘了在AndroidManifest.xml中加入

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

以上皆参考网上资料实现。

以上实现方法会存在两份照片,指定目录中有一份,图库中有一份,且我发现图库中的图片拍出来的效果较模糊

下面获取较清晰图片的解决办法

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button takePhoto , btn_setting , btn_write , btn_mske , btn_icon;

    private Uri imageUri;//图片路径
    private String filename;//图片名称
    private File operateFile;//操作文件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        /**
         * android.os.FileUriExposedException: file:///storage/emulated/0/ilive/images/photophoto.jpeg
         * exposed beyond app through ClipData.Item.getUri()
         * 下面三行解决此处问题
         * **/
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        builder.detectFileUriExposure();

        requestPermissions();   //权限申请

        takePhoto = this.findViewById(R.id.btn_photo);
        takePhoto.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_photo:
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //照相
                filename = saveFileName();
                operateFile = new File(filename);
                imageUri = Uri.fromFile(operateFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);   //指定图片输出地址
                startActivityForResult(intent,1008);    //启动照相
                break;
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode,resultCode,data);
        if (resultCode != RESULT_OK){
            deleteFile(operateFile);   //将指定路径图片删去仅保留图库图片
            Toast.makeText(MainActivity.this, "ActivityResult返回码错误!", Toast.LENGTH_SHORT).show();
            return;
        }
        switch (requestCode){
            case 1008:

                saveCameraImage(data);
                deleteFile(operateFile);    //将指定路径图片删去仅保留图库图片
                break;
        }
    }

    /**【申请手机相机和内存读取权限】**/
    public void requestPermissions(){
        String [] permissions = new String[] {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO,
        };
        ActivityCompat.requestPermissions(MainActivity.this,permissions,100);
    }



    /**【保存相机拍的图片】**/
    public void saveCameraImage(Intent data){

        FileInputStream inputStream = null;

        try {
            inputStream = new FileInputStream(filename);
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            /**【通知媒体库更新数据库,在图库中能看到图片,且图片是另外再保存一张】**/
            MediaStore.Images.Media.insertImage(getContentResolver(),bitmap,null,null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**【保存文件的名字以及目录】**/
    private String saveFileName(){
        String path = Environment.getExternalStorageDirectory().toString() + "/DCIM/youtu/";
        File newFolder = new File(path);
        if (!newFolder.exists()){
            boolean isfal = newFolder.mkdirs();
            Log.e("isfal","创建目录:"+path+"<-状态->" + isfal);
        }
        Log.e("path","路径:"+path);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date(System.currentTimeMillis());
        String name = path + format.format(date) +".jpg";
        Log.e("FileName","保存文件路径和名字:" + name);
        return name;
    }

    /**【删除文件】**/
    private void deleteFile(File file){
        if (file.exists()){     //文件是否存在
            if (file.isFile()){ //是否是文件
                boolean isDel = file.delete();
                Log.e("文件删除状态","<-=->"+isDel);
            }
        }
    }
}

以上能实现保留原图。