从“最近图像”文件夹中选择图像时,图片路径为空

时间:2015-09-29 10:14:08

标签: android android-intent bitmap gallery image-uploading

我正在为我的应用程序上传图像,这里当我从我的图库中选择一个图像时工作正常,现在如果我从“最近”文件夹中选择相同的图像,图片路径为空,我无法上传图片你能帮我解决一下这个问题。

以下是我的代码供您参考:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // find the views
    image = (ImageView) findViewById(R.id.uploadImage);
    uploadButton = (Button) findViewById(R.id.uploadButton);
    takeImageButton = (Button) findViewById(R.id.takeImageButton);
    selectImageButton = (Button) findViewById(R.id.selectImageButton);

    selectImageButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            selectImageFromGallery();

        }
    });

    takeImageButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Intent cameraIntent = new Intent(
                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);

            /*
             * Picasso.with(MainActivity.this) .load(link) .into(image);
             */

        }
    });

    // when uploadButton is clicked
    uploadButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // new ImageUploadTask().execute();
            Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT)
                    .show();
            uploadTask();
        }
    });
}

protected void uploadTask() {
    // TODO Auto-generated method stub
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG, 100, bos);
    byte[] data = bos.toByteArray();
    String file = Base64.encodeToString(data, 0);
    Log.i("base64 string", "base64 string: " + file);
    new ImageUploadTask(file).execute();
}

/**
 * Opens dialog picker, so the user can select image from the gallery. The
 * result is returned in the method <code>onActivityResult()</code>
 */
public void selectImageFromGallery() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"),
            PICK_IMAGE);
}

/**
 * Retrives the result returned from selecting image, by invoking the method
 * <code>selectImageFromGallery()</code>
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == PICK_IMAGE && resultCode == RESULT_OK
            && null != data) {

        Uri selectedImage = data.getData();
        Log.i("selectedImage", "selectedImage: " + selectedImage.toString());
        String[] filePathColumn = { MediaStore.Images.Media.DATA };

        Cursor cursor = getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);

        /*
         * Cursor cursor = managedQuery(selectedImage, filePathColumn, null,
         * null, null);
         */

        cursor.moveToFirst();

        // int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        int columnIndex = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String picturePath = cursor.getString(columnIndex);
        Log.i("picturePath", "picturePath: " + picturePath);
        cursor.close();

        decodeFile(picturePath);

    }

}


public void decodeFile(String filePath) {
    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, o);

    // The new size we want to scale to
    final int REQUIRED_SIZE = 1024;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    bitmap = BitmapFactory.decodeFile(filePath, o2);

    image.setImageBitmap(bitmap);
}

以下是我的log供您参考:

3 个答案:

答案 0 :(得分:0)

使用它在ImageView中显示图像

Uri selectedImage = data.getData();
imgView.setImageUri(selectedImage);

或者使用它..

Bitmap reducedSizeBitmap = getBitmap(selectedImage.getPath());
imgView.setImageBitmap(reducedSizeBitmap);

如果你想减小图像尺寸并且想要获得位图

   private Bitmap getBitmap(String path) {

        Uri uri = Uri.fromFile(new File(path));
        InputStream in = null;
        try {
            final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
            in = getContentResolver().openInputStream(uri);

            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(in, null, o);
            in.close();


            int scale = 1;
            while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) >
                    IMAGE_MAX_SIZE) {
                scale++;
            }

            Bitmap b = null;
            in = getContentResolver().openInputStream(uri);
            if (scale > 1) {
                scale--;
                // scale to max possible inSampleSize that still yields an image
                // larger than target
                o = new BitmapFactory.Options();
                o.inSampleSize = scale;
                b = BitmapFactory.decodeStream(in, null, o);

                // resize to desired dimensions
                int height = b.getHeight();
                int width = b.getWidth();

                double y = Math.sqrt(IMAGE_MAX_SIZE
                        / (((double) width) / height));
                double x = (y / height) * width;

                Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,
                        (int) y, true);
                b.recycle();
                b = scaledBitmap;

                System.gc();
            } else {
                b = BitmapFactory.decodeStream(in);
            }
            in.close();

            Matrix matrix = new Matrix();
            //set image rotation value to 90 degrees in matrix.
            matrix.postRotate(90);
            //supply the original width and height, if you don't want to change the height and width of bitmap.
            b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);

            return b;
        } catch (IOException e) {
            Log.e("", e.getMessage(), e);
            return null;
        }
    }

答案 1 :(得分:0)

我遇到了同样的问题。尽管还有其他使用URI的方法,但也有一种获取正确路径的方法。 看到这个问题: retrieve absolute path when select image from gallery kitkat android

有点过时了。这是更新的代码。

        Uri originalUri = data.getData();

        final int takeFlags = data.getFlags()
                & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        // Check for the freshest data.
        getContentResolver().takePersistableUriPermission(originalUri, takeFlags);

            /* now extract ID from Uri path using getLastPathSegment() and then split with ":"
            then call get Uri to for Internal storage or External storage for media I have used getUri()
            */
        String id = originalUri.getLastPathSegment().split(":")[1];
        final String[] imageColumns = {MediaStore.Images.Media.DATA};
        final String imageOrderBy = null;

        Uri uri = getUri();
        String filePath = "path";

        Cursor imageCursor = getContentResolver().query(uri, imageColumns,
                MediaStore.Images.Media._ID + "=" + id, null, imageOrderBy);

        if(imageCursor.moveToFirst()) {
            filePath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
        }

private Uri getUri() {
    String state = Environment.getExternalStorageState();
    if(!state.equalsIgnoreCase(Environment.MEDIA_MOUNTED))
        return MediaStore.Images.Media.INTERNAL_CONTENT_URI;

    return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}

确保您具有读取的外部存储权限。另外,请注意,您的书写方式在kitkat之前有效。不幸的是,即使不再保证它可以工作,大多数示例似乎仍然使用该方法。

答案 2 :(得分:-1)

我遇到了同样的问题,并从这个github示例https://github.com/maayyaannkk/ImagePicker

中找到了解决方案

这是解决您问题的方法

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

    if (requestCode == PICK_IMAGE && resultCode == RESULT_OK
            && null != data) {

        Uri selectedImage = data.getData();
        String   imageEncoded = getRealPathFromURI(getActivity(), selectedImageUri);
        Bitmap selectedImage = BitmapFactory.decodeFile(imageString);
        image.setImageBitmap(selectedImage);
    }
}

这些方法用于获取图片网址

public String getRealPathFromURI(Context context, Uri contentUri) {
    OutputStream out;
    File file = new File(getFilename(context));

    try {
        if (file.createNewFile()) {
            InputStream iStream = context != null ? context.getContentResolver().openInputStream(contentUri) : context.getContentResolver().openInputStream(contentUri);
            byte[] inputData = getBytes(iStream);
            out = new FileOutputStream(file);
            out.write(inputData);
            out.close();
            return file.getAbsolutePath();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

private byte[] getBytes(InputStream inputStream) throws IOException {
    ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];

    int len = 0;
    while ((len = inputStream.read(buffer)) != -1) {
        byteBuffer.write(buffer, 0, len);
    }
    return byteBuffer.toByteArray();
}

private String getFilename(Context context) {
    File mediaStorageDir = new File(context.getExternalFilesDir(""), "patient_data");
    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        mediaStorageDir.mkdirs();
    }

    String mImageName = "IMG_" + String.valueOf(System.currentTimeMillis()) + ".png";
    return mediaStorageDir.getAbsolutePath() + "/" + mImageName;

}