将相机图像保存到SD卡,检索并上传到Firestore存储

3
我在将图片保存到SD卡时遇到困难。不知何故,它保存到了内部存储文件夹中。我也不能检索到存储图像的文件路径,或者我没有正确地检索文件。因此,我无法将图片上传到Firestore Storage。
如果有人能帮助,我已经包含了所有的代码。我目前正在使用三星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>

file_paths.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>

活动(Kotlin)

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

我只能在“内部存储/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'并将下载URL保存在'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);
            });
}

如果有人能帮忙,那将不胜感激。这个问题困扰我整整一周了。


<external-files-path> 你不能有三个相同的。 - blackapps
FileProvider不能正常用于可移动介质上的文件。除非您知道适用于29及以下版本的技巧。 - blackapps
感谢您联系我们。我会尝试替换FileProvider并寻找另一种保存图像的方法。 - M.Strachan
在内部处理图像时,没有必要将其提供给任何人。 - Martin Zeitler
这可能会有所帮助,https://www.tutlane.com/tutorial/android/android-external-storage-with-examples#:~:text=在Android中,外部存储是,使用FileInputStream对象读取媒体文件。 - puspak saha
1个回答

0
最好创建一个对话框,让用户选择他们想要存储照片的位置。请记住,有很多不同型号的安卓设备,他们可能会有所不同。如果你仍然想要这样做,我在这里找到了相同的问题。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接