从图库中选择一张图片 Android

choose an image from gallery Android

我正在编写一个代码,使用户能够从图库中选择个人资料图片。至此代码如下

(1) 在activity下的字段中,我声明了一个按钮,一个图像视图和一个静态整数。

private Button btnChooseProfile;
private ImageView ivProfile;
private static final int RESULT_LOAD_IMAGE = 1;

(2) 现在,我通过 onCreate 方法让它们真正出现在屏幕上。

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

    btnChooseProfile = (Button) findViewById(R.id.btnChooseProfile);
    ivProfile = (ImageView) findViewById(R.id.ivProfile);

    btnChooseProfile.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, RESULT_LOAD_IMAGE);
        }
};

(3) 最后,我覆盖了 onActivityResult 方法来定义单击 btnChooseProfile 按钮后发生的情况。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String imagePath = cursor.getString(columnIndex);
            cursor.close();

            ivProfile.setImageBitmap(BitmapFactory.decodeFile(imagePath));
        }
    }

当我 运行 代码时,我设法访问了画廊。选择图像后,我希望 imageview 包含选定的图片,但应用程序会以某种方式结束。

我已经阅读了该站点中建议的很多解决方案,并且代码片段本身似乎没有问题。如果我遗漏了什么,请给我一些建议,我们将不胜感激。

谢谢。

编辑这里是 logcat。 (日志级别:调试)

07-13 15:15:25.961  28110-28110/com.marshall.gruppo E/﹕ Device driver API match
    Device driver API version: 29
    User space API version: 29
07-13 15:15:25.961  28110-28110/com.marshall.gruppo E/﹕ mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Tue Jul 22 19:59:34 KST 2014
07-13 15:15:26.051  28110-28110/com.marshall.gruppo D/OpenGLRenderer﹕ Enabling debug mode 0
07-13 15:15:28.726  28110-28110/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 153K, 6% free 14269K/15064K, paused 9ms, total 9ms
07-13 15:15:28.751  28110-28110/com.marshall.gruppo D/AbsListView﹕ Get MotionRecognitionManager
07-13 15:15:28.831  28110-28110/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 115K, 6% free 14329K/15088K, paused 12ms, total 12ms
07-13 15:15:28.861  28110-28110/com.marshall.gruppo I/dalvikvm-heap﹕ Grow heap (frag case) to 33.649MB for 19955728-byte allocation
07-13 15:15:28.876  28110-28119/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 1K, 3% free 33816K/34580K, paused 13ms, total 13ms
07-13 15:15:33.401  28110-28110/com.marshall.gruppo W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
07-13 15:15:37.681  28110-28110/com.marshall.gruppo D/AbsListView﹕ onDetachedFromWindow

我不会做你在 onActivityResult 中做的所有事情...它是主线程,因此不推荐访问 DB (ContentProvider) 和解码 Bitmap。启动 AsyncTask 或其他东西。

有时返回的数据为空(是的,它发生了)- 确保您的代码为空。添加一些日志。

我相信你应该不错

这可能是图片尺寸问题。试试这个代码来缩小你的图片。

 Bitmap photo;
        File file = new File(picturePath);
        int file_size = Integer
                .parseInt(String.valueOf(file.length() / 1024));
        if (file_size > 2048)
        {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 4;
            photo = BitmapFactory.decodeFile(picturePath, options);
        } else if (file_size > 1024)
        {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            photo = BitmapFactory.decodeFile(picturePath, options);
        } else
            photo = BitmapFactory.decodeFile(picturePath);
        ivProfile.setImageBitmap(photo);
public Bitmap compressImage(String imageUri) {

        String filePath = imageUri;
        // String filePath = getRealPathFromURI(imageUri);
        Bitmap scaledBitmap = null;

        BitmapFactory.Options options = new BitmapFactory.Options();

        // by setting this field as true, the actual bitmap pixels are not
        // loaded in the memory. Just the bounds are loaded. If
        // you try the use the bitmap here, you will get null.
        options.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeFile(filePath, options);

        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;

        // max Height and width values of the compressed image is taken as
        // 816x612

        /*
         * float maxHeight = 816.0f; float maxWidth = 612.0f;
         */
        float maxHeight = 1080.0f;
        float maxWidth = 800.0f;

        float imgRatio = actualWidth / (float) actualHeight;
        float maxRatio = maxWidth / (float) maxHeight;

        // width and height values are set maintaining the aspect ratio of the
        // image

        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;

            }
        }

        // setting inSampleSize value allows to load a scaled down version of
        // the original image

        options.inSampleSize = calculateInSampleSize(options, actualWidth,
                actualHeight);

        // inJustDecodeBounds set to false to load the actual bitmap
        options.inJustDecodeBounds = false;

        // this options allow android to claim the bitmap memory if it runs low
        // on memory
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];

        try {
            // load the bitmap from its path
            bmp = BitmapFactory.decodeFile(filePath, options);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();

        }
        try {
            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,
                    Bitmap.Config.ARGB_8888);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2,
                middleY - bmp.getHeight() / 2, new Paint(
                        Paint.FILTER_BITMAP_FLAG));

        // check the rotation of the image and display it properly
        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);

            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION, 0);
            Log.d("EXIF", "Exif: " + orientation);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 3) {
                matrix.postRotate(180);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 8) {
                matrix.postRotate(270);
                Log.d("EXIF", "Exif: " + orientation);
            } 

            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
                    true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return scaledBitmap;
        }