我如何从Android执行S3分段上传

huangapple go评论55阅读模式
英文:

How do I do S3 multipart upload from Android

问题

概述:我有一个应用程序,它使用以下方法将图像和小型音频文件上传到S3:

  1. 从后端使用安全API获取预签名URL。
  2. 使用Retrofit上传到预签名URL。

问题:现在我需要支持像视频这样的较大文件,因此我正在考虑实现多部分上传。

先前的解决方案:在我以前做的一个Web应用程序中,我使用Uppy S3 Multipart插件来处理多部分上传。该插件通过回调提供了为各个部分提供签名URL的方式。其他所有操作(拆分成部分、上传)都由插件处理。

当前情况:我已经搜索了几天,寻找Android中与Uppy S3 Multipart类似的可行替代方案,但没有找到。以下是我的调查结果:

  1. Android没有类似的库。
  2. 官方AWS文档建议使用AWS Amplify,并在所有示例代码中使用Cognito,但我的项目中没有Cognito。
  3. 一些示例显示使用AWS-Android-SDK创建一个使用应用程序中存储的凭据的S3Client,这对我也不是一个选项。

我已经走得最远的地方:看起来最有希望的选项是AWS移动SDK中的TransferUtility类:

val transferUtility =
   TransferUtility.builder()
      .context(c)
      .awsConfiguration(awsConfiguration)
      .s3Client(s3Client)
      .build()

但我应该从哪里获取awsConfigurations3ClientBasicSessionCredentials类与我的问题有关吗?

问题:是否有实际方法可以开始工作?唯一的方法是手动处理拆分和上传吗?为什么Android中还没有Uppy的替代方案?

英文:

Overview: I have an app that uploads images and small audio files to S3 using the following approach:

  1. Get a presigned URL from the backend using a secure API.
  2. Upload to the presigned URL using Retrofit.

Problem: Now I need to support larger files like videos, so I am looking into implementing multi-part uploads.

Previous Solution: In a web app I did a while back, I had used the Uppy S3 Multipart plugin to handle multi-part uploads. The plugin had callbacks through which I could provide it with signed URLs for the individual parts. Everything else (splitting into parts, uploading) was handled by the plugin.

Current Situation: I have been searching for days for a viable alternative to Uppy S3 Multipart in Android but have not found one. Here are my findings:

  1. There are no similar libraries for Android.
  2. The official AWS docs suggest using AWS Amplify and make use of Cognito in all sample codes, which I don’t have in my project.
  3. Some examples show using the AWS-Android-SDK to create an S3Client using credentials stored in the app, which is also not an option for me.

The farthest I've gotten: The option that looked the most promising is the TransferUtility class in the AWS Mobile SDK:

val transferUtility =
   TransferUtility.builder()
      .context(c)
      .awsConfiguration(awsConfiguration)
      .s3Client(s3Client)
      .build()

But where do I get the awsConfiguration and s3Client from? Also is BasicSessionCredentials class somehow related to my problem?

Questions: Is there an actual way to get this started? Is the only way to do this to manually handle the splitting and uploading? Why isn’t there an Uppy alternative yet in Android?

答案1

得分: 1

关于您当前的情况,AWS移动SDK中的TransferUtility类确实可以用于处理将多个组件迁移到S3。要使用这个类,您需要拥有awsConfigurations3Client对象。

AWSConfiguration类可用于创建awsConfiguration对象,通常位于您的应用程序的res/raw目录中。此文件包含您的AWS配置设置,如S3存储桶名称和字段。您可以像这样创建AWSConfiguration示例:

val awsConfiguration = AWSConfiguration(applicationContext)

接下来,您需要使用AWS移动SDK创建s3Client的实例。s3ClientAmazonS3Client类的一个实例,您可以按以下方式创建:

val s3Client = AmazonS3Client(AWSMobileClient.getInstance())

请注意,您需要将AWS移动SDK的要求和依赖项添加到您的项目中。

现在,如果您想使用TransferUtility启动一个分段上传,您可以使用upload()方法。以下是如何使用它的示例:

val transferUtility = TransferUtility.builder()
    .context(applicationContext)
    .awsConfiguration(awsConfiguration)
    .s3Client(s3Client)
    .build()

val uploadObserver = transferUtility.upload(bucketName, objectKey, file)

总之,您可以使用AWS移动SDK中的TransferUtility类来处理Android应用程序中的分段上传。按照上述描述获取awsConfigurations3Client对象,然后使用TransferUtilityupload()方法启动上传过程。

英文:

Regarding your current scenario, the TransferUtility class from the AWS Mobile SDK can indeed be used to handle the migration of multiple components to S3. To use this class, you will need to have the awsConfiguration and s3Client objects.

The AWSConfiguration class can be used to create the awsConfiguration object, which is usually located in your app's res/raw directory. This file contains your AWS configuration settings, such as S3 bucket names and fields. You can create an AWSConfiguration example like this:

val awsConfiguration = AWSConfiguration(applicationContext)

Next, you need to create an instance of s3Client using the AWS Mobile SDK. s3Client is an instance of the AmazonS3Client class, which you can create as follows.

val s3Client = AmazonS3Client(AWSMobileClient.getInstance())

Please note that you will need to add AWS Mobile SDK requirements and dependencies to your project.

Now, if you want to initiate a multipart upload using TransferUtility, you can use the upload() method. Here is an example of how you can use it.

val transferUtility = TransferUtility.builder()
    .context(applicationContext)
    .awsConfiguration(awsConfiguration)
    .s3Client(s3Client)
    .build()

val uploadObserver = transferUtility.upload(bucketName, objectKey, file)

In summary, you can use the TransferUtility class from the AWS Mobile SDK to handle multipart uploads in your Android app. Obtain the awsConfiguration and s3Client objects as described above, then use the upload() method of TransferUtility to start the upload process.

答案2

得分: 0

我最终使用AWS安全令牌服务来解决了这个问题。我从我们的OAuth安全的API中获取临时凭证,避免了在应用程序中存储凭证的需求。然后我像这样使用TransferUtility

val secrets = //fetch from API

val awsCredentials: AWSCredentials = BasicSessionCredentials(secrets.accessKey, secrets.secretKey, secrets.sessionToken)
val s3Client = AmazonS3Client(awsCredentials, Region.getRegion(Regions.AP_SOUTHEAST_1))
val awsConfiguration = AWSConfiguration(context)
val transferUtility = TransferUtility.builder().context(context).awsConfiguration(awsConfiguration).s3Client(s3Client).build()
val uploadObserver: TransferObserver = transferUtility.upload(media.key, media.file)

希望这能帮助将来来到这里的任何人。

英文:

I ended up solving this using AWS Security Token Service. I fetch temporary credentials from our Oauth secured api, avoiding the need to store credentials in the app itself. Then I use the TransferUtility like this:

<!-- language: kt-->
val secrets = //fetch from API

val awsCredentials: AWSCredentials = BasicSessionCredentials(secrets.accessKey, secrets.secretKey, secrets.sessionToken)
val s3Client = AmazonS3Client(awsCredentials, Region.getRegion(Regions.AP_SOUTHEAST_1))
val awsConfiguration = AWSConfiguration(context)
val transferUtility = TransferUtility.builder().context(context).awsConfiguration(awsConfiguration).s3Client(s3Client).build()
val uploadObserver: TransferObserver = transferUtility.upload(media.key, media.file)

Hope this helps anyone coming here in the future.

huangapple
  • 本文由 发表于 2023年6月2日 00:11:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383832.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定