拍照并将其保存在Android的内部存储中

时间:2020-01-22 04:02:30

标签: android camera

我正在尝试使用按钮拍照,并将其保存在内部存储器中并在内部存储器中显示,但是在文件中发现错误。 如果我尝试使用局部变量Uri应用程序崩溃

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    iv1 = (ImageView)findViewById(R.id.iv);
    b1 = findViewById(R.id.b1);
    b1.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View v) {
         takePicture(v);
      }
    });

//下面用来检查权限

  if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
        {
          ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
        }
    }

//下面的拍照方法

        private void takePicture(View v)
        {
            Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
             **file** = Uri.fromFile(getOutputMediaFile());

            i.putExtra(MediaStore.EXTRA_OUTPUT, **file**);


            startActivityForResult(i, 100);
        }

//get the picture
        private static File getOutputMediaFile()
        {
            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES), "FotoAula");

            if (!mediaStorageDir.exists()){
                if (!mediaStorageDir.mkdirs()){
                    return null;
                }
            }

            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            return new File(mediaStorageDir.getPath() + File.separator +
                    "IMG_"+ timeStamp + ".jpg");
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == 100) {
                if (resultCode == RESULT_OK) {

                    iv.setImageURI(**file**);
                }
            }
        }
    }

4 个答案:

答案 0 :(得分:0)

您可以尝试-

private static final int CAMERA_IMAGE = 1010;
private Uri imageUri;

private void captureImage() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File f = new File(Environment.getExternalStorageDirectory(), "my_image.jpg");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        imageUri = Uri.fromFile(f);
        startActivityForResult(intent, CAMERA_IMAGE);
    }

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

            if (requestCode == CAMERA_IMAGE && resultCode == Activity.RESULT_OK) {
                if(imageUri != null){
                    Uri selectedImage = imageUri;
                    getContentResolver().notifyChange(selectedImage, null);
                    Bitmap bitmap = getBitmapFromUri(imageUri.getPath());
                    if(bitmap != null){
                        iv.setImageBitmap(bitmap);                
                    }
                }
            } 
        }

答案 1 :(得分:0)

首先在清单文件中声明此块以供使用相机。

<uses-feature android:name="android.hardware.camera" android:required="false" /> 

<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" /> 

然后检查Android 23 SDK及更高版本的权限。

if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
        {
          ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,  Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
        }
    }

声明新图片文件的方法。

private File getPictureFile() {
  String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
  String pictureFile = "ZOFTINO_" + timeStamp;
  File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
  File image = File.createTempFile(pictureFile,  ".jpg", storageDir);
  pictureFilePath = image.getAbsolutePath();
  return image; 
}

然后创建拍照方法。

private void takePicture() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(cameraIntent, REQUEST_PICTURE_CAPTURE);

    File pictureFile = null;
    try {
        pictureFile = getPictureFile();
    } catch (IOException ex) {
        Toast.makeText(this,
                "Photo file can't be created, please try again",
                Toast.LENGTH_SHORT).show();
        return;
    }
    if (pictureFile != null) {
        Uri photoURI = FileProvider.getUriForFile(this,
                "com.zoftino.android.fileprovider",
                pictureFile);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
        startActivityForResult(cameraIntent, REQUEST_PICTURE_CAPTURE);
    }
} 
}

然后在清单文件中定义FileProvider。

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.zoftino.android.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_list"></meta-data>
</provider> 

在xml文件中定义FileProvider的文件路径列表,并将其保存在res / xml文件夹中。

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

最后,您从OnActivityResult方法获取相机结果。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_PICTURE_CAPTURE && resultCode == RESULT_OK) {
        File imgFile = new  File(pictureFilePath);
        if(imgFile.exists())            {
            // You will use imgFile.
        }
    }
} 

答案 2 :(得分:0)

首先希望您已经在清单中定义了FileProvider

替换行

**file** = Uri.fromFile(getOutputMediaFile());

使用

Uri file = FileProvider.getUriForFile(this,
      "com.example.android.fileprovider",
      getOutputMediaFile());

注意:此处“ com.example.android.fileprovider”是清单中FileProvider中定义的android:authorities

答案 3 :(得分:0)

我尝试使用此方法。

 public void saveImage(View view) throws IOException {
        BitmapDrawable draw = (BitmapDrawable) iv1.getDrawable();
        Bitmap bitmap = draw.getBitmap();

        FileOutputStream outStream = null;
        File sdCard = Environment.getExternalStorageDirectory();
        File dir = new File(sdCard.getAbsolutePath() + "/YourFolderName");
        dir.mkdirs();
        String fileName = String.format("%d.jpg", System.currentTimeMillis());
        File outFile = new File(dir, fileName);
        outStream = new FileOutputStream(outFile);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
        outStream.close();


        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(Uri.fromFile(outFile));
        sendBroadcast(intent);
    }