如何在 Android 中将文件上传到 Cloudinary 时显示进度?
Posted
技术标签:
【中文标题】如何在 Android 中将文件上传到 Cloudinary 时显示进度?【英文标题】:How to show progress while upload file to Cloudinary in Android? 【发布时间】:2015-05-20 03:22:31 【问题描述】:我实现了将文件上传到 Cloudinary 的功能。
Cloudinary cloudinary = new Cloudinary(Constants.CLOUDINARY_URL);
try
FileInputStream is = new FileInputStream(new File(filePath));
Uploader uploader = cloudinary.uploader();
Map map = uploader.upload(is, new HashMap());
return map;
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
现在我想在上传时显示上传进度条。 但我找不到任何回调函数来获取上传百分比。 请帮我。 谢谢。
【问题讨论】:
目前不支持。 Cloudinary 的路线图是在 android 集成库中添加对进度指示的支持。 嗨 Itay,这方面有什么进展吗? 【参考方案1】:cprakashagr 的答案实际上可以创造奇迹。只是为了详细说明他的答案,您需要通过执行以下操作从 github 下载最新的 cloudinary 库:
git clone https://github.com/cloudinary/cloudinary_java.git
那你就得根据他的链接进行修改了:
https://github.com/cloudinary/cloudinary_java/pull/41
您不能使用 Android Studio 进行这些更改,因为这是一个 maven 项目,因此您需要使用另一个 IDE,例如 IntelliJ。
这就是我进行更改的方式:
-
您需要添加类:UploadCallback
您需要将类 Uploader 替换为他的类:https://github.com/cprakashagr/cloudinary_java/blob/master/cloudinary-core/src/main/java/com/cloudinary/Uploader.java
完成此操作后,进入 cloudinary_java 的主文件夹,然后进入终端。去输入mvn install
然后按回车。您将看到 mvn 将为您目录中的不同文件夹构建 jar。构建完成后,例如,如果您导航到 cloudinary-core
文件夹,您将看到 cloudinary-core
jar。
您必须从文件夹中复制cloudinary-core
jar 并将其添加到您的android 项目根目录下的android 项目“libs”文件夹中。完成此操作后,它会出现在那里,右键单击 Android Studios 中的 jar,然后单击 "Add as Library"
,以便 android studios 将其添加为依赖项。
cloudinary-android
jar 不需要添加为 jar,因为您可以从 gradle 中获取副本。您的最终 gradle 文件应如下所示:
compile('com.cloudinary:cloudinary-android:1.2.2')
exclude module: 'cloudinary-core'
compile files('/Users/XXX/Documents/myApp/libs/cloudinary-core-1.4.2-SNAPSHOT.jar')
重建你的android studio项目,你会看到UploadCallback
现在是一个你可以在你的android项目中使用的对象。这是您知道您的 jar 构建已成功修改的方式。
现在在服务类中,添加您的代码以进行云端直接上传。您需要将代码放在服务类中,因为您无法在 UI 线程上执行网络操作,并且如果您尝试会收到错误消息:
Map config = new HashMap();
config.put("cloud_name", "XXX");
Cloudinary mobileCloudinary = new Cloudinary(config);
Map map = null;
try
map = mobileCloudinary.uploader()
.uploadLarge(this,
intent.getSerializableExtra(getString(R.string.file)),
ObjectUtils.asMap("public_id", 123),
"tags", "myphoto",
"folder", "mylibrary",
"unsigned", true,
"upload_preset", "XXX"),
51200);
catch (IOException e)
e.printStackTrace();
String imageUrl = map.get("url").toString();
Timber.e("imageUrl " + imageUrl);
您必须将缓冲区设置为足够大(但不能太大)以确保实际调用您的回调。当我第一次尝试这段代码时,我将缓冲区设置为非常大的值,比如200000000
,并且没有调用回调,因为上传会一次完成。如果将其设置为较小的值,例如2048
,则会定期调用回调,但是上传会变得很慢。由您决定适合您的应用的适当大小。对我来说是51200
,这意味着每上传 50kb 的文件,就会发生回调。
一旦它开始工作,您需要将服务类的进度信息传输回您的活动类,以便您可以在屏幕上显示进度。我使用messageHandler
这样做。这是我的服务类中的消息方法:
public void sendMessage(float progress)
Message message = Message.obtain();
message.arg1 = Math.round(progress);
try
messageHandler.send(message);
catch (RemoteException e)
e.printStackTrace();
这是我在活动课上的messageHandler
:
public class MessageHandler extends Handler
@Override
public void handleMessage(final Message message)
Timber.e("transfer: " + message.arg1);
【讨论】:
【参考方案2】:cloudinary 团队尚未实施回调。尽管周围的工作很少。
检查这个link。
您需要从 cloudinary 源导入或构建新的 JAR。为此,您要么使用此 repository,要么将所需的 changes 添加到其原始存储库。
如果您有任何问题,请告诉我。
编辑:关于如何使用它
在您的 Android 项目 (src/java
dir) 中导入这两个云源:
-
Cloudinary Core Lib Source
Cloudinary Android Lib Source
按照我的pull 请求进行更改。
并根据更改的签名调用方法uploadLarge。喜欢:
cloudinary.uploader().uploadLarge(UploadCallback : uploadCallback, File : file, Map : options, int : bufferSize);
对于缓冲区大小,请确保您至少使用 5242881。这是来自 cloudinary 服务器的限制。最小数据包至少需要 5.001 MB。
【讨论】:
感谢您的回答。您帮我解决了一个困扰了很长时间但不知道如何解决的问题。我设法实施了您的解决方案,并在上面的回答中进行了更详细的阐述,以便其他人也可以在这个紧迫的问题上获得帮助。 嗨,Simon,感谢您试用我的实现。我会更新关于如何使用它的答案。事实上,我们不必做那么长时间的工作。 好的 - 如果您有足够的声望点,您可以编辑我的答案以使我的实施更容易,否则,如果您不这样做,您可以随时添加您的答案以帮助其他访问此线程的人。 我已经更新了,伙计。我希望这将为所有人减少很多时间。 :) 干杯。如果您有任何问题,请告诉我。 谢谢!我不知道使用 5242881 的最小缓冲区大小。那相当大,缓冲区大小决定了调用侦听器的频率。因此,如果我上传小于 5mb 的图片,则根本不会调用侦听器,并且进度将直接跳到 100%,中间没有任何显示。以上是关于如何在 Android 中将文件上传到 Cloudinary 时显示进度?的主要内容,如果未能解决你的问题,请参考以下文章
在 1 个请求中将多个文件从 Android 上传到 AppEngine