试图从相机获取图像以上传到Firebase时遇到困难 - java.lang.IllegalStateException:uri不能为null

时间:2017-12-08 05:08:45

标签: android firebase kotlin android-camera uri

我一直在阅读这里关于这个主题的每篇文章(以及文档),由于某种原因,我无法让它发挥作用。我到达用户拍照的位置,点击复选标记继续,然后应用崩溃。

特别是在这一行:

val filepath = mFirebaseStorage.child("Users").child(prefs.UID).child(uri.lastPathSegment)

我的代码看起来像这样:

onLaunchCamera - 当用户从提示框中选择“相机”时调用

private fun onLaunchCamera() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    //Ensure there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(packageManager) != null) {
        var photoFile: File? = null
        try {
            photoFile = createImageFile()
        } catch (e: IOException) {
            //log error
            Log.e(TAG, e.toString())
        }
        //continue only if file was successfully created!
        if (photoFile != null) {
            val photoURI = FileProvider.getUriForFile(this,
                    "com.android.projectrc.fileprovider",
                    photoFile)
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
        }
    }
}

onActivityResult

override protected fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)

    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        val progressDialog = indeterminateProgressDialog("Uploading...")
        progressDialog.show()
        Log.d(TAG,"URI:: ${photoURI}")
        val uri = data.data

        val filePath = mFirebaseStorage.child("Users").child(prefs.UID)
                .child("ProfileImage").child(uri.lastPathSegment)
        filePath.putFile(photoURI!!).addOnSuccessListener(OnSuccessListener <UploadTask.TaskSnapshot >() {
            fun onSuccess(taskSnapshot : UploadTask.TaskSnapshot) {
                toast("Upload Successful!")
                progressDialog.dismiss()
            }
        }).addOnFailureListener(OnFailureListener () {
            fun onFailure(e : Exception) {
                Log.e(TAG, e.toString())
                toast("Upload Failed!")
            }
        });
        //val bundle = data.extras
    }
}

createImageFile

private fun createImageFile(): File {
    // Create an image file name
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)
    val imageFileName = "JPEG_" + timeStamp + "_";
    val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
    val image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.absolutePath;
    return image
}

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE" />

<application
    android:name=".App"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.android.projectrc.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

files_path.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.android.projectrc/files/Pictures" />
</paths>

当控制台输出时,即使是photoURI也显示为null - 我非常感到失望并且会感激任何帮助!

1 个答案:

答案 0 :(得分:1)

answer to this related question说明当URIEXTRA_OUTPUT意图上作为ACTION_IMAGE_CAPTURE传递时,URI不会作为有关intent参数的数据返回到onActivityResult()

这意味着您必须在生成类变量时将URI保存在类变量中,以便在onActivityResult()中可用。您似乎已将photoURI声明为类变量,并且您打算使用此代码在onLaunchCamera()中定义它的值:

        val photoURI = FileProvider.getUriForFile(this,
                "com.android.projectrc.fileprovider",
                photoFile)

但是val正在创建photoURI的新实例,并且该值不会根据需要存储在类字段中。删除val