从 uri 获取 FileInputStream 以上传图片
Posted
技术标签:
【中文标题】从 uri 获取 FileInputStream 以上传图片【英文标题】:Get FileInputStream from uri to upload image 【发布时间】:2022-01-16 19:40:55 【问题描述】:我在没有 WRITE_EXTERNAL_PERMISION 和 READ_EXTERNAL_PERMISION
的情况下成功地从图库或相机中获取图像
现在我想将该图像上传到 FTP 服务器
ImageSetter.kt
class ImageSetter(
private val activity: FragmentActivity,
private val imageView: ImageView,
val uriCallback:(uri:Uri?) -> Unit,
) : DefaultLifecycleObserver
private lateinit var getContent: ActivityResultLauncher<String>
private lateinit var dispatchTakePicture: ActivityResultLauncher<Uri>
private val registry = activity.activityResultRegistry
private var uri: Uri? = null
override fun onCreate(owner: LifecycleOwner)
getContent =
registry.register(
"select-key",
owner,
ActivityResultContracts.GetContent()
)
it?.let
uriCallback.invoke(it)
this.uri = it
imageView.setImageURI(uri)
dispatchTakePicture =
registry.register(
"take-keys",
owner,
ActivityResultContracts.TakePicture()
)
if (it)
Log.d("takePicture", "Success")
imageView.setImageURI(uri)
else
Log.d("takePicture", "Failed")
fun selectImage()
val items = arrayOf("Select an image", "Take Photo")
AlertDialog.Builder(activity)
.setItems(items) dialog, which ->
Log.d("dialog", dialog.toString())
Log.d("which", which.toString())
when(which)
0 -> getContent.launch("image/*")
1 -> takePicture()
.show()
private fun takePicture()
val filename = UUID.randomUUID().toString() + ".jpg"
val path = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val file = File(path, filename)
uri = FileProvider.getUriForFile(activity,
BuildConfig.APPLICATION_ID + ".provider", file);
uriCallback(uri)
dispatchTakePicture.launch(uri)
Log.d("Uri", uri.toString())
为了将 图像文件上传到服务器,我需要 InputStream 但我无法获取 原始图像文件 将其发布到服务器.
我是否需要任何许可才能这样做?
MainActivity.kt
class MainActivity : AppCompatActivity()
private lateinit var observer: ImageSetter
private lateinit var photoIv:ImageView
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
photoIv = findViewById(R.id.photoIv)
observer = ImageSetter(this, photoIv) photoUri->
var openInputStream = contentResolver?.openInputStream(photoUri!!)
var format = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
var file = File(filesDir, "$format.jpg")
var fileoutputStream = FileOutputStream(file)
openInputStream?.copyTo(fileoutputStream)
openInputStream?.close()
fileoutputStream.close()
fileAbsolutPath = file.absolutePath
lifecycle.addObserver(observer)
observer.selectImage()
编辑
我有一个工作班可以将 fileInputStream 上传到具有方法的 FTP 服务器
public static boolean uploadImageFileOnFtpServer(FileInputStream inputStream, String clientFileName)
...
现在我只想弄清楚如何从 Uri 获取 fileInputStream。
【问题讨论】:
我认为 InputStream 可以。请确认。 进一步:如果您使用相机拍摄图像,您可以使用文件提供程序作为文件路径。所以在这种情况下,你有一个路径并且可以使用 FileInputStream。 我有 uri,如何将我的 uri 转换为 fileInputStrem。请参阅编辑@blackapps 你对我说的话没有反应。val file = File(path, filename)
您有一个 File 实例,因此您可以将它用于新的 FileInputStream。此外,如果您只有一个 uri,您也可以将 InputStream 传递给您的上传函数。
have a working class to upload fileInputStream to FTP Server which has a method
将其更改为采用 InputStream。或者为 InputStream 添加一个重载成员。但正如你现在拥有的那样,你也可以传递一个 InputStream 。我已经说过了。
【参考方案1】:
您需要传递 URI 来获取文件并将此文件输入流并上传到服务器。
var file=getFileFromUri(uri!!)
val inputStream: InputStream = FileInputStream(file)
并从以下方法获取文件。
fun getFileFromUri(uri: Uri): File?
if (uri.path == null)
return null
var realPath = String()
val databaseUri: Uri
val selection: String?
val selectionArgs: Array<String>?
if (uri.path!!.contains("/document/image:"))
databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
selection = "_id=?"
selectionArgs = arrayOf(DocumentsContract.getDocumentId(uri).split(":")[1])
else
databaseUri = uri
selection = null
selectionArgs = null
try
val column = "_data"
val projection = arrayOf(column)
val cursor = contentResolver.query(
databaseUri,
projection,
selection,
selectionArgs,
null
)
cursor?.let
if (it.moveToFirst())
val columnIndex = cursor.getColumnIndexOrThrow(column)
realPath = cursor.getString(columnIndex)
cursor.close()
catch (e: Exception)
Log.i("GetFileUri Exception:", e.message ?: "")
val path = if (realPath.isNotEmpty()) realPath else
when
uri.path!!.contains("/document/raw:") -> uri.path!!.replace(
"/document/raw:",
""
)
uri.path!!.contains("/document/primary:") -> uri.path!!.replace(
"/document/primary:",
"/storage/emulated/0/"
)
else -> return null
return File(path)
【讨论】:
以上是关于从 uri 获取 FileInputStream 以上传图片的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有 OutOfMemory 错误的情况下从 FileInputStream 获取字节数组