【问题标题】:Get uri from camera intent in android从android中的相机意图获取uri
【发布时间】:2014-01-27 18:22:05
【问题描述】:

点击

 takePic.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent m_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                imageUri = getImageUri();
                m_intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(m_intent, REQUEST_IMAGE_CAPTURE);
            }
        });

关于结果:

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_IMAGE_CAPTURE
                    && resultCode == RESULT_OK) {   

                Log.d("test1",""+imageUri);
                Intent shareIntent = new Intent(this, SharePicForm.class);
                shareIntent.putExtra("photo",""+imageUri);
                startActivity(shareIntent);
            }

        }

getImageUri()

private Uri getImageUri(){
        Uri m_imgUri = null;
        File m_file;
        try {
            SimpleDateFormat m_sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            m_curentDateandTime = m_sdf.format(new Date());
            m_imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + m_curentDateandTime + ".jpg";
            m_file = new File(m_imagePath);
            m_imgUri = Uri.fromFile(m_file);
        } catch (Exception p_e) {
        }
        return m_imgUri;
    }

我想要实现的很简单,调用相机意图并获取结果照片的 uri。但似乎不同的设备不一致,在我的设备上它根本不起作用。我试图将路径存储在公共变量上,但是当我检索它时,它为空,是否有正式和标准的方式来实现它并且应该在所有设备上工作?另外,有什么方法可以不提供自定义路径,而是从相机意图中获取默认的 uri 路径?

感谢您的帮助

【问题讨论】:

  • 使用 onSavedInstance() 和 onRestoreInstanceState() 保存并重新获得图像路径。

标签: android android-intent camera


【解决方案1】:

如果您的设备不尊重cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,您仍然可以使用

Uri imageUri = data.getData();

onActivityResult(int requestCode, int resultCode, Intent data)。但在大多数情况下,问题在于 RAM 是有限的,并且系统会破坏您的活动,以便为相机应用程序提供足够的内存来满足您的意图。因此,返回结果时,你的activity的字段没有初始化,你应该按照Amit的建议,执行onSavedInstance()onRestoreInstanceState()

【讨论】:

  • data.getData 在大多数情况下返回 null
  • @zakjma:要接收data.getData(),您不应根据自己的意图额外传递 MediaStore.EXTRA_OUTPUT
  • data.getData() 在我的设备(android 7.1.1)上返回 null,即使我没有按我的意图传递 MediaStore.EXTRA_OUTPUT。 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, CAMERA_REQUEST_CODE);
  • @zakjma 这可能是您设备的错误行为,但看起来这个data.getData() 似乎不再包含在官方文档中。请注意,他们鼓励您使用 FileProvider 而不是 Uri,因此这种转变确实有意义。
  • @zakjma 是对的,即使不通过 MediaStore.EXTRA_OUTPUT,我也没有得到 data.data
【解决方案2】:

首先确保你的目录已经创建......

final String dir =  Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/Folder/";
     File newdir = new File(dir); 
     newdir.mkdirs();

在按钮单击时调用此函数。

private void capturarFoto() {
 String file = dir+DateFormat.format("yyyy-MM-dd_hhmmss", new Date()).toString()+".jpg";


File newfile = new File(file);
            try {
                newfile.createNewFile();
            } catch (IOException e) {}       

            Uri outputFileUri = Uri.fromFile(newfile);

            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

            startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}

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

    if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
        Log.d("Demo Pic", "Picture is saved");


    }
}

确保您在清单中添加权限

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

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

【讨论】:

  • 此代码是否适用于有 sdcard 和没有 sdcard 的手机?
  • 通过隐式Intent使用不需要摄像头权限。只有实现自己的相机时才需要它
  • data 在 this 中返回 null。我很困惑
【解决方案3】:

要获取缩略图,您可以使用:

val imageBitmap = data.extras.get("data") as Bitmap

要全面了解:
具体步骤见from here(官方文档)

您可以从docs 了解更多信息。

【讨论】:

    【解决方案4】:

    经过大量研究,我找到了这个解决方案。为了清楚起见,我为这个问题创建了一个完整的应用程序,其目的是打开相机点击照片并将图像设置为 ImageView 的 ImageBitmap。这个问题中询问的代码从第二个块开始,即 setView() 方法,它位于 onCreate() 方法下面,然后我们有 onActivityResult() 方法

    这是应用程序的演示。

    下面我附上了 MainActivity.java 文件

    package com.cr7.opencamera;
    
    import android.Manifest;
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.content.ContentValues;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.graphics.Bitmap;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.MediaStore;
    import android.util.Log;
    import android.widget.Button;
    import android.widget.ImageView;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.app.ActivityCompat;
    import androidx.core.content.ContextCompat;
    
    import java.io.IOException;
    
    public class MainActivity extends AppCompatActivity {
    
        private Button buttonCaptureImageFromCamera;
        private Uri imageUri;
        private ImageView imageViewCameraImage;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // Button that will open the camera
            buttonCaptureImageFromCamera = findViewById(R.id.buttonCaptureImageFromCamera);
            // ImageView that will store the image
            imageViewCameraImage = findViewById(R.id.imageViewCameraImage);
            askPermission();
        }
    
    

    这是获取图像的 Uri 所需要的,这里 imageUri 是一个全局变量,因此它可以在 onActivityResult() 方法中使用

        // Sets OnClickListener for the button if storage permission is given
        private void setView() {
            buttonCaptureImageFromCamera.setOnClickListener(v -> {
                String fileName = "new-photo-name.jpg";
                // Create parameters for Intent with filename
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.TITLE, fileName);
                values.put(MediaStore.Images.Media.DESCRIPTION, "Image capture by 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, 1231);
            });
        }
    

    这是 onActivityResult 方法。这里我使用了 imageUri,即 Uri 类型的全局变量,它在上面的 setView() 方法中的按钮的 OnClickListener 中初始化。

        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == 1231 && resultCode == Activity.RESULT_OK) {
                try {
                    ContentResolver cr = getContentResolver();
                    try {
                        // Creating a Bitmap with the image Captured
                        Bitmap bitmap = MediaStore.Images.Media.getBitmap(cr, imageUri);
                        // Setting the bitmap as the image of the
                        imageViewCameraImage.setImageBitmap(bitmap);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (IllegalArgumentException e) {
                    if (e.getMessage() != null)
                        Log.e("Exception", e.getMessage());
                    else
                        Log.e("Exception", "Exception");
                    e.printStackTrace();
                }
            }
        }
    

    剩余代码...

    
        // Asking user for storage permission
        public void askPermission() {
            // Checking if the permissions are not granted.
            if (
                    ContextCompat.checkSelfPermission(
                            this,
                            android.Manifest.permission.WRITE_EXTERNAL_STORAGE
                    ) != PackageManager.PERMISSION_GRANTED ||
                            ContextCompat.checkSelfPermission(
                                    this,
                                    android.Manifest.permission.READ_EXTERNAL_STORAGE
                            ) != PackageManager.PERMISSION_GRANTED
            ) {
                // If not granted requesting Read and  Write storage
                ActivityCompat.requestPermissions(this, /*You can ask for multiple request by adding
                more permissions to the string*/new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                Manifest.permission.READ_EXTERNAL_STORAGE}, 60);
            } else {
                // If permissions are granted we proceed by setting an OnClickListener for the button
                // which helps the user pick the image
                setView();
            }
        }
    
        // This method is called after the permissions have been asked i.e. the dialog that says
        // allow or deny
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                               @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            // Now by default we assume that the permission has not been granted
            boolean allPermissionsGranted = false;
            // Now we check if the permission was granted
            if ( requestCode == 60 && grantResults.length > 0) {
                // If all the permissions are granted allPermissionsGranted is set to true else false
                allPermissionsGranted = grantResults[0] == PackageManager.PERMISSION_GRANTED
                        &&
                        grantResults[1] == PackageManager.PERMISSION_GRANTED;
            }
            // If permissions are granted we call the setView Method which prompts the user to pick
            // an Image either by the clicking it now or picking from the gallery
            if ( allPermissionsGranted ) {
                setView();
            }
        }
    }
    

    这些代码块是按顺序排列的,也就是说,如果你合并所有这些块,你会得到完整的 MainActivity.java 类。

    如果你想实现这个应用程序,你需要创建一个布局文件,其中包含一个 ID 为“imageViewCameraImage”的 ImageView 和一个 ID 为“buttonCaptureImageFromCamera”的按钮。

    希望这会有所帮助。我知道这很长,我通过写这篇文章让它更长。 问候, 乔尔

    【讨论】:

      【解决方案5】:

      只需使用这个 Uri imageUri = data.getData();

      【讨论】:

      • 从相机,data.getData() 方法总是返回 null。你错了
      猜你喜欢
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-27
      相关资源
      最近更新 更多