Uri.parse(path)在Android 4.4.2中返回null

时间:2015-02-05 12:01:05

标签: java android nullpointerexception uri

我有一个允许用户在墙上上传照片的应用。

该代码适用于大多数用户,但我已经报告过上传照片时应用程序崩溃了。

问题不在于从相机拍摄照片,而是在必须拍摄照片的路径时。

导致此问题的Android版本是4.4.2,但我不明白如何修复它。

发布一些代码:

activityResult

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode == RESULT_OK) {

        if (requestCode == CAMERA_PIC_REQUEST) {

            try {
                //picUri is a global variable Uri
                picUri = data.getData();

                cropImage();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        else if(requestCode == PIC_CROP) {

            try{
                //thumbnail is a global variable Bitmap
                thumbnail = MediaStore.Images.Media.getBitmap(context.getContentResolver(), cropImageUri);

                setImage();
            }
            catch (Exception e) {

                e.printStackTrace();
            }

        }
    }
}

热到裁剪图片:

public void cropImage() {

    try {

        Intent cropIntent = new Intent("com.android.camera.action.CROP");
        //indicate image type and Uri
        cropIntent.setDataAndType(picUri, "image/*");
        //set crop properties
        cropIntent.putExtra("crop", "true");
        //indicate aspect of desired crop
        cropIntent.putExtra("aspectX", 1);
        cropIntent.putExtra("aspectY", 1);
        cropIntent.putExtra("scale", true);
        //indicate output X and Y
        cropIntent.putExtra("outputX", 700);
        cropIntent.putExtra("outputY", 700);
        //retrieve data on return
        cropIntent.putExtra("return-data", false);

        File f = createNewFile("CROP_");
        try{
            f.createNewFile();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        //cropImageUri is a global variable Uri
        cropImageUri = Uri.fromFile(f);


        cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri);

        //start the activity - we handle returning in onActivityResult
        startActivityForResult(cropIntent, PIC_CROP);
    }
    catch(ActivityNotFoundException anfe){

        anfe.printStackTrace();
    }
}

创建新文件:

private File createNewFile(String prefix) {

    if (prefix== null) {
        prefix="IMG_";
    }
    else if("".equalsIgnoreCase(prefix)) {
        prefix="IMG_";
    }

    File newDirectory = new File(Environment.getExternalStorageDirectory()+"/mypics/");
    if (!newDirectory.exists()) {
        if (newDirectory.mkdir()) {

        }
    }

    File file = new File(newDirectory,(prefix+System.currentTimeMillis()+".jpg"));
    if (file.exists()) {
        file.delete();
        try {
            file.createNewFile();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    return file;
}

然后当用户点击“发送”方法调用preUploadImage时:

public void preUploadImage() {

    UploadImage uploadImage = new UploadImage();

    Uri newUri = getImageUri(thumbnail);

    try{
        //   System.out.println("uri = "+picUri);
        uploadImage.upload(getRealPathFromURI(newUri));

    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

public Uri getImageUri(Bitmap inImage) {

    String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Title", null);

    return Uri.parse(path);
}

并在最后一行显示错误。

return Uri.parse(path); 

此行会导致NullPointerException

java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.<init>(Uri.java:468)
at android.net.Uri$StringUri.<init>(Uri.java:458)
at android.net.Uri.parse(Uri.java:430)
at com.delsorboilario.verdebio.ScriviDomanda.getImageUri(ScriviDomanda.java:584)
at com.delsorboilario.verdebio.ScriviDomanda.preUploadImage(ScriviDomanda.java:608)
at com.delsorboilario.verdebio.ScriviDomanda$6$4$2.run(ScriviDomanda.java:292)

2 个答案:

答案 0 :(得分:2)

看起来MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Title", null);会返回null。

形成MediaStore.Images.Media

的文档
  

插入图像并为其创建缩略图。

     

参数

     

cr要使用的内容解析器

     

source用于图像的流

     

title图像的名称

     

描述图像的描述

     

返回新创建的图像的URL,如果是图像,则返回null   因任何原因未能存储

答案 1 :(得分:2)

我没有尝试使用insertImage(),在这种情况下,您还不清楚为什么需要它。

首先,您似乎想要上传照片。为此,您只需要在File中创建的createNewFile()。如果您自己上传(例如,HttpUrlConnection,某些第三方库),您应该只能使用FileInputStream。即使上传代码确实需要Uri,您也可以尝试Uri.fromFile()Uri获取File,看看是否有效。

MediaStore 发挥作用的地方是让您的文件被编入索引,因此应用程序(查询MediaStore图像的用户)和用户(通过他们的用户)可以访问MTP通过USB线连接)。 MediaScannerConnection及其静态scanFile()方法是将文件编入索引的相当简单的方法。只需确保您的文件首先完全写入磁盘(例如,如果您自己编写文件,请在getFD().sync()之后FileOutputStream之前和flush()之前致电close()