简体   繁体   English

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

[英]Uri.parse(path) return null in Android 4.4.2

I have an app that allow user to upload a photo on wall. 我有一个应用程序,允许用户在墙上上传照片。

The code works well for the majority of users, but I have reported that the application crashes sometimes when uploading photo. 该代码对于大多数用户来说效果很好,但是我已经报告说,在上传照片时,应用程序有时会崩溃。

The problem is not in taking the pictures from the camera, but it is when you have to take the path of the picture. 问题不在于从相机拍摄照片,而在于您必须拍摄照片的路径。

The version of Android that is causing this problem is 4.4.2, but I do not understand how to fix it. 导致此问题的Android版本是4.4.2,但我不知道如何解决。

post some code: 发布一些代码:

activityResult : 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();
            }

        }
    }
}

hot to crop image: 热裁剪图像:

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();
    }
}

create new File: 创建新文件:

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;
}

then when a user click on "send" method preUploadImage is called: 然后,当用户单击“发送”方法时,将调用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);
}

and in the last row the error appears. 并在最后一行中显示错误。

return Uri.parse(path); 

this row cause a NullPointerException 该行导致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)

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

Form the documentation of MediaStore.Images.Media 形成MediaStore.Images.Media的文档

Insert an image and create a thumbnail for it. 插入图像并为其创建缩略图。

Parameters 参量

cr The content resolver to use cr要使用的内容解析器

source The stream to use for the image 源用于图像的流

title The name of the image 标题图像名称

description The description of the image 说明图像说明

Returns The URL to the newly created image, or null if the image failed to be stored for any reason 返回新创建图像的URL;如果由于任何原因导致图像存储失败,则返回null

I have not attempted to use insertImage() , and in this case, it is not quite clear why you would need it. 我没有尝试使用insertImage() ,在这种情况下,尚不清楚为什么需要它。

Primarily, it seems like you are looking to upload the photo. 首先,似乎您正在寻找上传照片。 For that, all you need is the File that you created in createNewFile() . 为此,您只需要在createNewFile()创建的File If you are uploading it yourself (eg, HttpUrlConnection , some third-party library), you should be able to just use the File or an InputStream on it. 如果您自己上传(例如HttpUrlConnection ,一些第三方库),则应该可以仅使用FileInputStream Even if the upload code really needs a Uri , you can try Uri.fromFile() to get a Uri from your File and see if that works. 即使上传代码确实需要Uri ,您也可以尝试Uri.fromFile()File获取Uri ,然后查看是否有效。

Where MediaStore does come into play is making your file be indexed and therefore accessible to apps (ones that query the MediaStore for images) and to users (via their MTP connection through their USB cable). MediaStore 开始发挥作用,是使您的文件进行索引,因此对应用程序(那些查询访问MediaStore进行图像)和用户(通过其通过USB数据线的连接MTP)。 MediaScannerConnection and its static scanFile() method are a fairly straightforward way to get the file indexed. MediaScannerConnection及其静态scanFile()方法是获取文件索引的一种非常直接的方法。 Just make sure your file is fully written to disk first (eg, if you are writing the file yourself, call getFD().sync() on your FileOutputStream after flush() and before close() ). 只需确保首先将文件完全写入磁盘即可(例如,如果您是自己写文件,则在flush()close()之前在FileOutputStream上调用getFD().sync() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM