首页 > 解决方案 > 将相机图像保存到 SD 卡,检索并上传到 Firestore 存储

问题描述

我在 SD 卡中保存图像时遇到困难。由于某种原因,它保存到内部存储文件夹。我也无法检索存储图像的文件路径。或者我没有正确检索文件。因此,我无法将图像上传到 Firestore 存储。

我已经包含了我的所有代码,如果有人可以提供帮助,将不胜感激。目前使用的是三星 Galaxy S10。这是为了支持我的 Firestore 应用程序的离线功能。

我保存的图像仅存储在

Internal Storage / Android / data / com.mly.Live /files / Pictures /

我宁愿将其保存在 SD 卡文件夹中...

安卓清单

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

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

文件路径.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
    name="my_images"
    path="Android/data/com.mly.Live/files/Pictures/"/>
<external-files-path
    name="my_debug_images"
    path="/storage/emulated/0/Android/data/com.mly.Live/files/Pictures/"/>
<external-files-path
    name="my_root_images"
    path="/"/>
</paths>

活动(科特林)

private fun dispatchTakePictureIntent() {
    Intent(MediaStore.ACTION_IMAGE_CAPTURE).also {
        takePictureIntent -> takePictureIntent.resolveActivity(packageManager)?.also {

            val photoFile: File? = try {
                createImageFile()
            } catch (ex: IOException) {
                null
            }
            photoFile?.also {
                photoURI = FileProvider.getUriForFile(
                        this,
                        "com.mly.Live.fileprovider",
                        it
                )
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
            }
        }
    }
}

@Throws(IOException::class)
private fun createImageFile(): File {
    val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
   
    val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)!!

    return File.createTempFile(
            "${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
    ).apply {
        currentPhotoPath = absolutePath
    }
}


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

    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        // Shows a small thumbnail image
        binding?.issueImage?.setImageURI(photoURI)
    }
}

当我保存 Firestore 文档时...我将“imageRemoteSent”设置为 false(意味着图像尚未保存到 Firestore 存储)和 imageLocal 的文件路径...

photoURI.toString() 给了我...

content://com.mly.Live.fileprovider/my_root_images/Pictures/54b4beb1-e30e-4f64-8bd9-9ed37695b474_7839622760179284029.jpg

currentPhotoPath 给了我...(我匹配了 imageName 来说明差异)。

/storage/emulated/0/Android/data/com.mly.Live/files/Pictures/54b4beb1-e30e-4f64-8bd9-9ed37695b474_7839622760179284029.jpg

我只能在“InternalStorage/Android/data/com.mly.Live/files/Pictures/”中看到这些照片

AddIssueActivity (Kotlin)

private fun saveIssue1() {

    val db = FirebaseFirestore.getInstance()

    val data = hashMapOf(
            "type" to binding?.issueTypeSpinner?.selectedItem.toString(),
            "imageRemoteSent" to false,
            "imageLocal" to photoURI.toString(),
            "imageRemote" to "",
    )

    db.collection("Issues")
            .add(data)
            .addOnSuccessListener { documentReference ->

            }
            .addOnFailureListener { e ->

            }

}

HomeActivity (Java) 实时 Firestore 监听器...监听问题为“imageRemoteSent == false”并尝试将它们上传到 Firestore 存储。当用户在 onCreate 中登录应用程序时调用此方法。我无法正确地将其上传到 Firestore。成功上传到 Firestore 存储后,我更改了“imageRemoteSent == true”并将 downloadURL 保存在“imageRemote”中。

void checkForRemoteImages() {

    FirebaseHelper.getInstance().getIssueLocalImageCollection((issues -> {

        this.issue = issues;

        if (issue.size() > 0) {

            for (Issue object: issue) {

                String imageName = UUID.randomUUID().toString();

                FirebaseStorage storage = FirebaseStorage.getInstance();
                StorageReference storageRef = storage.getReference();

                StorageReference imageReference = storageRef.child("partInfoImagesFolder").child(imageName);

                Uri uriP = Uri.parse(object.getImageLocal());

                Uri uploadUri = Uri.fromFile(new File(uriP.toString()));

                imageReference.putFile(uploadUri)
                        .addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
                            @Override
                            public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {

                                imageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                                    @Override
                                    public void onSuccess(Uri uri) {

                                        Uri url = uri;

                                        Toast.makeText(HomeActivity.this, "Upload Successful!", Toast.LENGTH_SHORT).show();

                                        DocumentReference washingtonRef = FirebaseFirestore.getInstance().collection("Issues").document(object.getDocumentId());

                                        washingtonRef
                                                .update("imageRemoteSent", true,
                                                        "imageRemote", url)
                                                .addOnSuccessListener(new OnSuccessListener<Void>() {
                                                    @Override
                                                    public void onSuccess(Void aVoid) {
                                                        Log.d("TAG WORK!!", "DocumentSnapshot successfully updated!");
                                                    }
                                                })
                                                .addOnFailureListener(new OnFailureListener() {
                                                    @Override
                                                    public void onFailure(@NonNull Exception e) {
                                                        Log.w("TAG FAIL", "Error updating document", e);
                                                    }
                                                });
                                    }
                                });
                            }

                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.w("TAG FAIL", "Error updating document", e);
                            }
                        });

                }

            } else {
                Toast.makeText(HomeActivity.this, "There are no Images to upload to firestore!", Toast.LENGTH_SHORT).show();
            }
    }));
}

FirebaseHelper 活动 (Java)

public void getIssueLocalImageCollection(FireStoreDataRetrieved<List<Issue>> action){
    FirebaseFirestore.getInstance().collection(ISSUES_REF).whereEqualTo("imageRemoteSent",false)
            //.whereEqualTo("issueActive", true)
            .orderBy("issueDate", Query.Direction.DESCENDING)
            .addSnapshotListener((snapshot, err)->{
                List<DocumentSnapshot> list =  snapshot.getDocuments();

                List<Issue> infos = new ArrayList<>();
                if(snapshot.size() > 0){
                    infos = snapshot.toObjects(Issue.class);
                }

                for (int index = 0 ;index < snapshot.size();index++)
                {
                    infos.get(index).setDocumentId(list.get(index).getId());
                }

                action.onFetch(infos);
            });
}

如果有人可以提供帮助,将不胜感激。整个星期都在看这个。

标签: javaandroidfirebasekotlingoogle-cloud-firestore

解决方案


最好创建一个对话框,让用户选择他们想要存储照片的位置。请记住,有大量的 Android 设备,它们可能会有所不同。如果你仍然想这样做,我在这里发现了同样的问题。

Android Studio:将图像保存在 SD 卡中


推荐阅读