如何配置 ACTION_IMAGE_CAPTURE 以将照片存储在 public 外部存储器中?

How to configure ACTION_IMAGE_CAPTURE to store the photo in public external storage?

Taking Photos Simply Documentation建议将设备相机拍摄的图像存储为"should be saved on the device in the public external storage"。但如何做到这一点?提供的示例显示了如何保存到私人文件夹!?

The provided example shows rather how to save to a private folder!?

不,不是。它显示了如何保存到 getExternalFilesDir()。这是 external storage 的一部分,用户可以访问。

如果您愿意,也欢迎您在 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) 下创建自己的子目录。不过,您将需要 WRITE_EXTERNAL_STORAGE 所有 API 级别,包括需要在 Android 6.0+.

上设置运行时权限

看到这段代码,它肯定会对你有所帮助:

私有无效 selectImage() {

    final CharSequence[] options = {"Take Photo", "Choose from Gallery"};

    AlertDialog.Builder builder = new AlertDialog.Builder(Maintenance.this);
    builder.setTitle("Add Photo!");
    builder.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {

            dialog.dismiss();
        }
    });
    builder.setItems(options, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (options[item].equals("Take Photo")) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                startActivityForResult(intent, 1);
            } else if (options[item].equals("Choose from Gallery")) {
                Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 2);

            } /*else if (options[item].equals("Cancel")) {
                dialog.dismiss();
            }*/
        }
    });
    builder.show();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == 1) {
            File f = new File(Environment.getExternalStorageDirectory().toString());

            for (File temp : f.listFiles()) {
                if (temp.getName().equals("temp.jpg")) {
                    f = temp;
                    break;
                }
            }
            try {
                Bitmap bitmap;
                BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();

                bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),
                        bitmapOptions);
                bitmap = Bitmap.createScaledBitmap(bitmap, 450, 450, false);
                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
                // byte[] imageBytes = bytes.toByteArray();
                // encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);

                Camera.setImageBitmap(bitmap);

                String path = android.os.Environment
                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath();
                f.delete();
                OutputStream outFile = null;
                file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
                //file.getPath();
                // String str = FileUtils.readFileToString(file, "UTF-8");
                image = file.getPath();
                String[] parts = image.split("/");
                encodedImage = parts[parts.length - 1];
                try {
                    outFile = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
                    outFile.flush();
                    outFile.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (requestCode == 2) {

            Uri selectedImage = data.getData();
            String[] filePath = {MediaStore.Images.Media.DATA};
            Cursor c = getContentResolver().query(selectedImage, filePath, null, null, null);
            c.moveToFirst();
            int columnIndex = c.getColumnIndex(filePath[0]);
            picturePath = c.getString(columnIndex);
            c.close();
            Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
            thumbnail = Bitmap.createScaledBitmap(thumbnail, 450, 450, false);
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            thumbnail.compress(Bitmap.CompressFormat.JPEG, 85, bytes);
            //  byte[] imageBytes = bytes.toByteArray();
            // encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
            image = picturePath;
            String[] parts = picturePath.split("/");
            encodedImage = parts[parts.length - 1];
            Camera.setImageBitmap(thumbnail);
        }
    }
} 

试试这个

//Click Picture from camera
        camera_image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.TITLE, "New Picture");
                values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera");
                imageUri = getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent, CAMERA_CLICK_RESULT);

            }


        });

这是结果

 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    //Get Image from Camera
    if (requestCode == CAMERA_CLICK_RESULT && resultCode == RESULT_OK) {

        Bitmap photo = null;
        try {
            photo = MediaStore.Images.Media.getBitmap(
                    getContentResolver(), imageUri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        selectedImage = getResizedBitmap(photo, 900);


        try {
            //Write file
            String filename = "/file_name";
            String dir_path = "Directory_Path";
            File file = new File(dir_path)
            file.mkdir();
            FileOutputStream fileOutputStream = new FileOutputStream(dir_path + filename);
            selectedImage.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);

            //Cleanup
            fileOutputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

//Resize Bitmap
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
    int width = image.getWidth();
    int height = image.getHeight();

    float bitmapRatio = (float) width / (float) height;
    if (bitmapRatio > 1) {
        width = maxSize;
        height = (int) (width / bitmapRatio);
    } else {
        height = maxSize;
        width = (int) (height * bitmapRatio);
    }
    return Bitmap.createScaledBitmap(image, width, height, true);
}

动作图像捕捉方法:

// OPEN CAMERA & TAKE PIC
private void dispatchTakePictureIntent() {

    try {

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

            // Create the File where the photo should go
            //File photoFile = null;

            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
                ex.printStackTrace();
                Log.e("takePic_IO_EX", ex + "");
            }

            //photoFile = createImageFile();

            // Continue only if the File was successfully created
            if (photoFile != null) {

                Uri photoURI = FileProvider.getUriForFile(this,
                        "com.example.appname.fileprovider",
                        photoFile);


                List<ResolveInfo> resInfoList = this.getPackageManager().queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);
                for (ResolveInfo resolveInfo : resInfoList) {
                    String packageName = resolveInfo.activityInfo.packageName;
                    this.grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
                /*takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                this.setResult(RESULT_OK, takePictureIntent);*/


                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
        Log.e("takePic_main_EX", e + "");
    }

}

onActivity:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {

        try {

            /*Log.e("mCurrentPhotoPath", mCurrentPhotoPath);
            Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
            Log.e("displayPic", "2");
            attendanceCameraBtn.setImageBitmap(bitmap);
            Log.e("displayPic", "3");*/

            try {
                if (photoFile.getAbsoluteFile().getTotalSpace() <= 10) {
                    //Log.e("fileSize==2==", photoFile.getTotalSpace() + "    ++++");
                    if (photoFile.isFile()) {
                        if (photoFile.exists()) {
                            photoFile.delete();
                            Toast.makeText(getApplicationContext(), "Photo Capture Failed, Please Retry!", Toast.LENGTH_LONG).show();
                        }
                    }

                } else {


                            //Do whatever you want here
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("file", e + "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            Log.e("displayPic_EX", e + "");
            Log.e("onActivityResult_EX", e + "");
        }
    } else {

        try {
            if (photoFile.isFile()) {
                if (photoFile.exists()) {
                    photoFile.delete();
                    Toast.makeText(getApplicationContext(), "Photo Capture Cancelled!", Toast.LENGTH_LONG).show();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("onActivityResult_els_EX", e + "");
        }
    }
}

private folder方法中创建图像目录和图像文件:

 private File createImageFile() throws IOException {

    // Create an image file name
    Random generate = new Random();
    int n = 10000;
    n = generate.nextInt(n);

    String nValue = String.valueOf(n);
    String fName = "Image-" + n;


    String filePath = getExternalFilesDir(Environment.DIRECTORY_PICTURES).toString();
    File dir = new File(filePath + "/app_images");

    if (!dir.exists()) {
                dir.mkdirs();
            }

    File image = File.createTempFile(
            fName,          /* prefix */
            ".jpg",         /* suffix */
            dir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();
    Log.e("mCurrentPhotoPath", mCurrentPhotoPath + "  ++++"); //Prints you the image file path
    return image;
}



try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
                ex.printStackTrace();
                Log.e("takePic_IO_EX", ex + "");
            }

并在 res 文件夹中创建一个名为 xml 的文件夹。在 xml 文件夹中,创建一个 xml file 并将其命名为 file_paths.xml。在 file_paths.xml

中提及此路径
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="Images" path="Android/data/" />
</paths>

全局声明File photoFile。 祝一切顺利!