努力尝试从相机获取图像以上传到 Firebase - java.lang.IllegalStateException: uri 不能为 null

Struggling with trying to get image from camera to upload to Firebase - java.lang.IllegalStateException: uri must not be null

我已经通读了这里所有 post 与该主题相关的内容(以及文档),但出于某种原因,我无法使其正常工作。我到了用户拍照的地步,点击 复选标记 继续,然后应用程序崩溃了。

特别是在这一行:

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

我的代码看起来像这样:

onLaunchCamera - 当用户从警告框

中选择"Camera"时调用
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 - 我很茫然,非常感谢任何帮助!

answer to this related question 说明当 URIACTION_IMAGE_CAPTURE 意图上作为 EXTRA_OUTPUT 传递时,URI 不会作为数据在 ACTION_IMAGE_CAPTURE 上返回onActivityResult().

的意图参数

这意味着您必须在生成 URI 时将其保存在 class 变量中,以便在 onActivityResult() 中可用。看来您已经将 photoURI 声明为 class 变量,并且您打算使用 onLaunchCamera():

中的此代码定义它的值
        val photoURI = FileProvider.getUriForFile(this,
                "com.android.projectrc.fileprovider",
                photoFile)

但是 val 正在创建 photoURI 的新实例,并且该值未按您的意愿存储在 class 字段中。删除 val.