Camera not working/saving when using Cache Uri as MediaStore.EXTRA_OUTPUT

后端 未结 3 466
滥情空心
滥情空心 2020-12-29 05:02

I am trying to get the full image after taking a picture from a Fragment.

If I use the Uri from the file (Uri.fromFile(file)), the camera w

相关标签:
3条回答
  • 2020-12-29 05:45

    Why not saving it in a new File

        final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
        root.mkdirs();
        final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
        final File sdImageMainDirectory = new File(root, fname);
        mImageUri = Uri.fromFile(sdImageMainDirectory);
    

    And then pass that uri to the intent

        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
    
    0 讨论(0)
  • 2020-12-29 05:55

    Try this is working like charm with me

    private String selectedImagePath = "";
        final private int PICK_IMAGE = 1;
        final private int CAPTURE_IMAGE = 2;
    
    public Uri setImageUri() {
            // Store image in dcim
            File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", "image" + new Date().getTime() + ".png");
            Uri imgUri = Uri.fromFile(file);
            this.imgPath = file.getAbsolutePath();
            return imgUri;
        }
    
    
        public String getImagePath() {
            return imgPath;
        }
    
    btnGallery.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    startActivityForResult(Intent.createChooser(intent, ""), PICK_IMAGE);
    
                }
            });
    
            btnCapture.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
                    startActivityForResult(intent, CAPTURE_IMAGE);
                }
            });
    
    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode != Activity.RESULT_CANCELED) {
                if (requestCode == PICK_IMAGE) {
                    selectedImagePath = getAbsolutePath(data.getData());
                    imgUser.setImageBitmap(decodeFile(selectedImagePath));
                } else if (requestCode == CAPTURE_IMAGE) {
                    selectedImagePath = getImagePath();
                    imgUser.setImageBitmap(decodeFile(selectedImagePath));
                } else {
                    super.onActivityResult(requestCode, resultCode, data);
                }
            }
    
        }
    
    
    public Bitmap decodeFile(String path) {
            try {
                // Decode image size
                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(path, o);
                // The new size we want to scale to
                final int REQUIRED_SIZE = 70;
    
                // Find the correct scale value. It should be the power of 2.
                int scale = 1;
                while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                    scale *= 2;
    
                // Decode with inSampleSize
                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = scale;
                return BitmapFactory.decodeFile(path, o2);
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return null;
    
        }
    
    public String getAbsolutePath(Uri uri) {
            String[] projection = { MediaColumns.DATA };
            @SuppressWarnings("deprecation")
            Cursor cursor = managedQuery(uri, projection, null, null, null);
            if (cursor != null) {
                int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            } else
                return null;
        }
    
    0 讨论(0)
  • 2020-12-29 06:02

    from android 26+ Uri.fromFile will not work, you should use File provider instead.

    AndroidManifest.xml

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <application
            .........
    
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.mydomain.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>
        </application>
    

    res/xml/file_paths.xml

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <external-path
            name="external"
            path="." />
    </paths>
    

    finally

    final Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    
    // output file
    File path = new File(Environment.getExternalStorageDirectory(), "tmp.mp4");
    
    // com.mydomain.fileprovider is authorities (manifest)
    // getUri from file
    Uri uri = FileProvider.getUriForFile(this, "com.mydomain.fileprovider", path);
    
    takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(takeVideoIntent, 99);
    

    tested on android 8.0 and 5.1.1

    Update: on some device built-in camera would not support for EXTRA_OUTPUT, so if you want to work on all devices, build your own camera module.

    0 讨论(0)
提交回复
热议问题