java - 将相机图像保存到 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);
});
}
如果有人可以提供帮助,将不胜感激。整个星期都在看这个。
解决方案
最好创建一个对话框,让用户选择他们想要存储照片的位置。请记住,有大量的 Android 设备,它们可能会有所不同。如果你仍然想这样做,我在这里发现了同样的问题。
推荐阅读
- python-3.x - 从内存中写入和读取 Excel
- typescript - 在泛型中使用类类型时如何匹配工厂的参数?
- elasticsearch - 使用 elasticsearch 插件的 Apache Drill 中的 DISTINCT SQL 查询返回代码生成错误
- vue.js - 如何修复 Vue 2 应用程序上的热重载?
- java - 与 Photoshop 手动调整图像大小相比,自动调整图像大小时,ML 模型的准确性较低
- sql - 先选择最大的日期,然后在sql【SQL Server】中选择相关的日期
- webgl - 背景颜色与 COLOR_BUFFER_BIT
- node.js - 反应停留在登录页面而不是重定向到仪表板
- java - 在 libGDX 中刷新 hud
- android - Class.forname(net.sourceforge.jtds.jdbc.driver) 错误