【问题标题】:Getting "Caused by: java.lang.NullPointerException: uri" when trying to set image after capturing it在捕获图像后尝试设置图像时出现“由:java.lang.NullPointerException:uri”引起
【发布时间】:2016-04-13 06:06:40
【问题描述】:

我有 2 个选项来设置图像,从图库中选择或捕获图像。

当用户从图库中选择图像时,它会返回一个叮当的 ImageView,当用户在捕获图像后尝试设置图像时,应用程序崩溃并出现以下错误:java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.abc.xyz/com.abc.xyz.Activity}: java.lang.NullPointerException: uri

这是我启动选择器的方式:

protected DialogInterface.OnClickListener mDialogListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int position) {
            switch (position) {
                case 0: // Take picture
                    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST);
                    break;
                case 1: // Choose picture
                    Intent choosePhotoIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    choosePhotoIntent.setType("image/*");
                    startActivityForResult(choosePhotoIntent, PICK_PHOTO_REQUEST);
                    break;
            }
        }
    };

这是我将图像设置到 ImageView 的方式:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == Activity.RESULT_OK) {

            if (requestCode == PICK_PHOTO_REQUEST || requestCode == TAKE_PHOTO_REQUEST) {
                if (data == null) {
                    // display an error
                    return;
                }
                Uri selectedImage = data.getData();
                String[] filePathColumn = { MediaStore.Images.Media.DATA };

                // error on the line below
                Cursor cursor = this.getContentResolver().query(selectedImage,
                        filePathColumn, null, null, null);
                //
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String picturePath = cursor.getString(columnIndex);
                cursor.close();

                Picasso.with(this)
                        .load(picturePath)
                        .into(hPic);
                hPicTag.setVisibility(View.INVISIBLE);
            }

        } else if (resultCode == Activity.RESULT_CANCELED) {
            Toast.makeText(getBaseContext(), "Something went wrong!", Toast.LENGTH_LONG).show();
        }

    }

请告诉我这里出了什么问题。

抱歉,问题的格式不正确。我还是个初学者。

【问题讨论】:

标签: android nullpointerexception uri picasso android-cursor


【解决方案1】:

某些Android版本获取路径的方式不同。为此,我使用以下 Util 类。

public class RealPathUtil {

    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API20(Context context, Uri uri){
        String filePath = "";
        String wholeID = DocumentsContract.getDocumentId(uri);

        // Split at colon, use second item in the array
        String id = wholeID.split(":")[1];

        String[] column = { MediaStore.Images.Media.DATA };

        // where id is equal to
        String sel = MediaStore.Images.Media._ID + "=?";

        Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                column, sel, new String[]{ id }, null);

        int columnIndex = cursor.getColumnIndex(column[0]);

        if (cursor.moveToFirst()) {
            filePath = cursor.getString(columnIndex);
        }
        cursor.close();
        return filePath;
    }


    public static String getRealPathFromURI_API11to19(Context context, Uri contentUri) {
        String[] proj = { MediaStore.Images.Media.DATA };
        String result = null;

        if(Looper.myLooper() == null) {
            Looper.prepare();
        }
        CursorLoader cursorLoader = new CursorLoader(
                context,
                contentUri, proj, null, null, null);
        Cursor cursor = cursorLoader.loadInBackground();

        if(cursor != null){
            int column_index =
                    cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            result = cursor.getString(column_index);
        } else {
            result = contentUri.getPath();
        }
        return result;
    }

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
        String[] proj = { MediaStore.Images.Media.DATA };
        Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        int column_index
                = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
}

现在根据设备的操作系统版本调用适当的方法为:

if (Build.VERSION.SDK_INT < 11) {
    RealPathUtil.getRealPathFromURI_BelowAPI11(...);
} else if(Build.VERSION.SDK_INT >= 11 && <= 19) {
    RealPathUtil.getRealPathFromURI_API11to19(...);
} else if(Build.VERSION.SDK_INT > 19){
    RealPathUtil.getRealPathFromURI_API20(...);
}

【讨论】:

  • 我实现了这个并在 String wholeID = DocumentsContract.getDocumentId(uri);错误消息---尝试在空对象引用上调用虚拟方法“java.util.List android.net.Uri.getPathSegments()”
【解决方案2】:

试试这样。 这肯定会对你有所帮助......经过测试......

  final String[] items = new String[]{"Camera", "Gallery"};            
            new AlertDialog.Builder(getActivity()).setTitle("Select Picture")
                    .setAdapter(adapter, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int item) {
                            if (items[item].equals("Camera")) {

                                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                                    startActivityForResult(intent, REQUEST_CAMERA);


                            } else if (items[item].equals("Gallery")) {
                                if (Build.VERSION.SDK_INT <= 19) {
                                    Intent intent = new Intent();
                                    intent.setType("image/*");
                                    intent.setAction(Intent.ACTION_GET_CONTENT);
                                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                                    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
                                } else if (Build.VERSION.SDK_INT > 19) {
                                    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                                    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
                                }
                            }
                        }
                    }).show();

        }


        // get result after selecting image from Gallery
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);

            if (requestCode == PICK_IMAGE && resultCode == getActivity().RESULT_OK && null != data) {
                Uri selectedImageUri = data.getData();
                String selectedImagePath = getRealPathFromURIForGallery(selectedImageUri);
                decodeFile(selectedImagePath);
            } else if (requestCode == REQUEST_CAMERA && resultCode == getActivity().RESULT_OK && null != data) {
                Bitmap photo = (Bitmap) data.getExtras().get("data");
                profileImage.setImageBitmap(photo);

                // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
                Uri tempUri = getImageUri(getActivity().getApplicationContext(), photo);

                // CALL THIS METHOD TO GET THE ACTUAL PATH
                File finalFile = new File(getRealPathFromURI(tempUri));
                decodeFile(finalFile.toString());
            }
        }

        public String getRealPathFromURIForGallery(Uri uri) {
            if (uri == null) {
                return null;
            }
            String[] projection = {MediaStore.Images.Media.DATA};
            Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
            if (cursor != null) {
                int column_index = cursor
                        .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            }
            return uri.getPath();
        }

        public Uri getImageUri(Context inContext, Bitmap inImage) {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
            String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
            return Uri.parse(path);
        }

        public String getRealPathFromURI(Uri uri) {
            Cursor cursor = getActivity().getContentResolver().query(uri, null, null, null, null);
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            return cursor.getString(idx);
        }


        // decode image
        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);
            Security connection = new Security(context);
            Boolean isInternetPresent = connection.isConnectingToInternet(); // true or false
            if (isInternetPresent) {
                // submit usr information to server
                //first upload file
                updateUserProfileImage();
                Log.i("IMAGEPATH", "" + imagePath);
            }
            profileImageView.setImageBitmap(bitmap);
        }

【讨论】:

  • 为什么要检查 sdk 版本?
  • @Rao..我用它来区分不同级别的 API
  • 是的,但是以更精确的方式。不过感谢您的帮助!
  • @Saurabh 我遵循了您的代码,而不是我在 Activity 上使用的片段,错误发生在下一行。 // 调用此方法从位图 Uri 中获取 URI tempUri = getImageUri(photo);引起:java.lang.NullPointerException:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-19
  • 2015-11-16
  • 1970-01-01
  • 2023-04-10
  • 2020-07-01
  • 2019-07-01
  • 2020-07-09
相关资源
最近更新 更多