选择一张照片或拍照并使用 onActivityResult() 两者都不起作用

Posted

技术标签:

【中文标题】选择一张照片或拍照并使用 onActivityResult() 两者都不起作用【英文标题】:Pick a photo or take a photo and use onActivityResult() for both not working 【发布时间】:2015-09-29 00:33:20 【问题描述】:

我正在尝试创建一个可以拍摄新照片或使用现有照片的应用。我让这两个功能分开工作,但不能一起工作。 Uri imageUri = data.getData(); 运行时应用程序崩溃。

代码如下:

 public void btnPhotoClicked(View v) 

    //Use to invoke a Camera
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    //Create a variable with the filepath generated by the android operating system, Like a baws

    File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
    if (pictureDirectory.exists()) 
        File test1 = new File(pictureDirectory, "100MEDIA/");
        if (test1.exists()) 
            pictureDirectory = test1;
         else 
            File test2 = new File(pictureDirectory, "100ANDRO/");
            if (test2.exists()) 
                pictureDirectory = test2;
             else 
                File test3 = new File(pictureDirectory, "Camera/");
                if (!test3.exists()) 
                    test3.mkdirs();
                
                pictureDirectory = test3;
            
        
     else 
        pictureDirectory = new File(pictureDirectory, "Camera/");
        pictureDirectory.mkdirs();
    

    String pictureName = getPictureName();
    File imageFile = new File(pictureDirectory, pictureName);
    Uri pictureUri = Uri.fromFile(imageFile);
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);


    //Start intent and anticipate result
    startActivityForResult(cameraIntent, CAMERA_RESULT);

这是protected void onActivityResult(int requestCode, int resultCode, Intent data)的代码

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

if (resultCode == RESULT_OK) 
    //if we are here everything processed successfully

    if (requestCode==IMAGE_GALLERY_REQUEST) 
        //If we are here we came from the Välj existerande build
        Log.d("MainActivity", data.toString());
        Toast.makeText(this, "IMAGE GALLERY_REQUEST", Toast.LENGTH_LONG).show();
        //the address of the image on the device SD-card
        Uri imageUri = data.getData();

        //Declare a stream to read the image data from the SD-card
        InputStream inputStream;

        //Getting a Input stream based upon the image uri
        try 
            //if it execute flawlessly
            inputStream = getContentResolver().openInputStream(imageUri);

            Bitmap image = BitmapFactory.decodeStream(inputStream);

            //show the image to the user

            mImageView.setImageBitmap(image);

         catch (FileNotFoundException e) 
            //show massage saying if the image is unavailable
            Toast.makeText(this, "Could not open image", Toast.LENGTH_LONG).show();
        

     else if (requestCode == CAMERA_RESULT) 
        //We are here because we have received a result from the camera
        Toast.makeText(this, "CAMERA RESULT", Toast.LENGTH_LONG).show();
        Log.d("MainActivity", data.toString());
        //the address of the image on the device SD-card
        Uri imageUri = data.getData();

        //Declare a stream to read the image data from the SD-card
        InputStream inputStream;

        //Getting a Input stream based upon the image uri
        try 
            //if it execute flawlessly
            inputStream = getContentResolver().openInputStream(imageUri);

            Bitmap image = BitmapFactory.decodeStream(inputStream);
            //show the image to the user

            mImageView.setImageBitmap(image);

         catch (FileNotFoundException e) 
            //show massage saying if the image is unavailable
            Toast.makeText(this, "Could not open image", Toast.LENGTH_LONG).show();
        



    


【问题讨论】:

会发生什么?你有什么错误吗?你能在这里分享错误的logcat吗? :) 赢得死亡:窗口4333a8f8 u0 com.example.akerberge.greifincident/com.example.akerberge.greifincident.MainActivity 【参考方案1】:

试试这个代替图片uri

if (resultCode == RESULT_OK)
        
            if (requestCode == 1) 
            
                File f = new File(Environment.getExternalStorageDirectory().toString());
                for (File temp : f.listFiles()) 
                
                  if (temp.getName().equals(tempFile)) 
                  
                        f = temp;
                        //File photo = new File(Environment.getExternalStorageDirectory(), tempFile);
                        break;
                    
                
                try
                
                    Bitmap bitmap;
                    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
                    bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),bitmapOptions); 
                    final int THUMBNAIL_SIZE = 100;
                    bitmap = Bitmap.createScaledBitmap(bitmap,THUMBNAIL_SIZE, THUMBNAIL_SIZE, false);

                    img.setImageBitmap(bitmap);

                    String path = android.os.Environment.getExternalStorageDirectory()+ File.separator;

                    File file = new File(path,tempFile);

                    updPath=file.toString();
                    imgSel = true;
                    success=true;
                
                catch (Exception e) 
                
                    Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
                
             
            else if (requestCode == 2) 
            
                try
                
                    Uri selectedImage = data.getData();
                    String[] filePath =  MediaColumns.DATA ;
                    Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null);
                    c.moveToFirst();
                    int columnIndex = c.getColumnIndex(filePath[0]);
                    String picturePath = c.getString(columnIndex);
                    c.close();
                    File outputPath= new File(android.os.Environment.getExternalStorageDirectory(), tempFile);
                    updPath = outputPath.toString();
                    copyFile(picturePath, updPath);

                    Bitmap thumbnail = (BitmapFactory.decodeFile(updPath));
                    final int THUMBNAIL_SIZE = 100;
                    thumbnail = Bitmap.createScaledBitmap(thumbnail,THUMBNAIL_SIZE, THUMBNAIL_SIZE, false);
                    ByteArrayOutputStream bytearroutstream = new ByteArrayOutputStream(); 
                    thumbnail.compress(Bitmap.CompressFormat.JPEG, 100,bytearroutstream);
                    img.setImageBitmap(thumbnail);
                    imgSel = true;
                    success=true;
                
                catch (Exception e) 
                
                    Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
                
            
        

【讨论】:

使用 File 类代替 Uri 不要使用整个代码,只需尝试其中的一部分并相应地更改您的代码【参考方案2】:

只有在返回的 Intent 中传回缩略图时,默认的 Android 相机应用才会返回非空 Intent。如果您将 EXTRA_OUTPUT 与要写入的 URI 一起传递,它将返回 null 意图,并且图片在您传入的 URI 中。

您可以通过查看 GitHub 上的相机应用源代码来验证这一点:

https://github.com/android/platform_packages_apps_camera/blob/gingerbread-release/src/com/android/camera/Camera.java#L1186

其中您的应用程序崩溃。因为getContentResolver().openInputStream(imageUri)调用空对象的方法。 imageUri 为空。

来自documentation:

公共静态最终字符串EXTRA_OUTPUT

在 API 级别 3 中添加Intent-extra 的名称,用于指示用于存储请求的图像或视频的内容解析器 Uri。

常量值:“输出”

所以,你调用 ACTION_IMAGE_CAPTURE 意图,你应该像这样传递额外的:

Intent photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri  = Uri.parse("file:///sdcard/photo.jpg");
photo.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(takePicture,requestCode);

然后在onActivityResult

if (requestCode == CAMERA_REQUEST_CODE) 
        if (resultCode == Activity.RESULT_OK) 
            File file = new File(Environment.getExternalStorageDirectory().getPath(), "photo.jpg");
            Uri uri = Uri.fromFile(file);
            Bitmap bitmap;
            try 
                bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                bitmap = crupAndScale(bitmap, 300); // if you mind scaling
                pofileImageView.setImageBitmap(bitmap);
             catch (FileNotFoundException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
             catch (IOException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            

        
    

更新

【讨论】:

在这个答案中图片是什么-----> picture.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri); Uri uri = Uri.parse("file:///sdcard/photo.jpg"); - 这是您的图像文件的 URI。在此文件中将保存来自相机的图像数据 对不起。我修正了这个错误 这里的问题是我无法从 else if 中接收到照片,因为我需要知道确切的名称 @EdvardÅkerberg,什么名字?您可以将其定义为常量,例如public static final String BUFFER_PHOTO_FILE = "file:///sdcard/blablabla.jpg",并在需要时使用它。我不明白你的问题。请更详细地描述它。我真的很想帮助你,但是,我不明白你。为什么需要知道确切的名称以及为什么不能使用像 BUFFER_PHOTO_FILE 这样的默认名称?

以上是关于选择一张照片或拍照并使用 onActivityResult() 两者都不起作用的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法将 segue 操作延迟到用户通过他们的照片库选择图像或拍照之后?迅速

h5 实现调用系统拍照或者选择照片并预览

Android -- 相机调用摄像头拍照 & 选择照片

如何调用android的拍照或本地相册选取,然后再实现相片上传服务器

如何选择一张图片来设置头像

我想让用户选择使用相机拍照或从库中挑选照片(ios-swift,apple example-foodtracker)