Android-我想向用户显示文件上传进度
我通过Android SDK中的默认HttpClient将照片上传到服务器。我想在用户界面上显示进度,有没有办法知道上传了多少?HttpUrlConnection可以吗?我没有使用该API,但请注意HttpClient不是特定于android的:Android-我想向用户显示文件上传进度,android,Android,我通过Android SDK中的默认HttpClient将照片上传到服务器。我想在用户界面上显示进度,有没有办法知道上传了多少?HttpUrlConnection可以吗?我没有使用该API,但请注意HttpClient不是特定于android的: org.apache.http.client.HttpClient 因此,如果你在谷歌上搜索“HttpClient progress”,有许多帖子可能是有用的 也可以考虑, 或使用AcyCtaskTo进行文件上传的实际过程,并使用PrimeCudio
org.apache.http.client.HttpClient
因此,如果你在谷歌上搜索“HttpClient progress”,有许多帖子可能是有用的
也可以考虑,
或使用AcyCtaskTo进行文件上传的实际过程,并使用PrimeCudio启动和停止进程。 您可以看到这段代码,我编写它是为了通过HTTP加载JSON数据,并使用process dialog
守则的主要部分是: private class LoadStoresTask extends AsyncTask<String, Void, List<Store>> {
@Override
protected List<Store> doInBackground(String... params) {
return WsiStoresClient.connect(params[0]);
}
@Override
protected void onPostExecute(List<Store> result) {
dismissDialog(BUSY_DIALOG_KEY);
}
}
私有类LoadStoresTask扩展异步任务{
@凌驾
受保护列表doInBackground(字符串…参数){
返回wsistoreclient.connect(参数[0]);
}
@凌驾
受保护的void onPostExecute(列表结果){
dismissDialog(忙对话框键);
}
}
我没有使用httpclient,但我已经使用异步任务做了一些您想要的事情
private class DownloadImageTask extends AsyncTask<String, Void,Bitmap>{
protected Bitmap doInBackground(String... urls) {
while (myProgress<length){
myProgress=myProgress+1;
myProgressBar.setProgress(myProgress);
}
return decodeImage(urls[0]);
}
protected void onPostExecute(Bitmap result) {
//dialog.dismiss();
imView.setImageBitmap(result);
}
protected void onPreExecute() {
/* Things to be done while execution of long running operation is
in progress. For example updating ProgressDialog */
dialog = ProgressDialog.show(BusinessCardActivity.this,
"Loading.........","Wait For Few Second", true);
}
}
私有类下载ImageTask扩展异步任务{
受保护位图doInBackground(字符串…URL){
而(myProgress对于我来说,HTTPClient不起作用。在flush调用之后,部分缓冲并作为总计发送的字节。起作用的是在套接字级别发送它
您可以为此使用HttpMultipartClient(2011年10月30日更新的链接):
指定每个部分的字节数,并更新while循环中的progressbar:
而((line=reader.readLine())!=null&&!headersEnd)
调用HttpMultipartClient,如下所示:
HttpMultipartClient httpMultipartClient = new HttpMultipartClient("bluppr.com", "/api/order/create", 80);
FileInputStream fis = new FileInputStream(path + fileName);
httpMultipartClient.addFile(fileName, fis, fis.available());
httpMultipartClient.setRequestMethod("POST");
httpMultipartClient.send();
在服务器端使用:
<?php
$target_path = "uploads/";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['name'])." has been uploaded " .$_POST["order"]. " post";
} else{
echo "There was an error uploading the file, please try again!";
}
?>
我用它制作Bluppr明信片,效果很好。如果您需要更多信息,请告诉我。1)请确保使用自己的线程在服务中执行上载
2) 要获得进度:将InputStream包装在这个类中,并使用一个对HttpClient具有多部分支持的httpime.jar库。我使用了一个线程来检查进度并更新通知中的progressbar
package com.hyves.android.service.upload;
import java.io.IOException;
import java.io.InputStream;
/**
* This outputstream wraps an existing outputstream and provides
* callbacks after certain amount of bytes to a HttpCallback
*
* @author tjerk
*/
public class ProgressNotifyingInputStream extends InputStream {
private InputStream wrappedStream;
private int count = 0;
private int totalSize;
/**
* Creates a new notifying outputstream which wraps an existing one.
* When you write to this stream the callback will be notified each time when
* updateAfterNumberBytes is written.
*
* @param stream the outputstream to be wrapped
* @param totalSize the totalsize that will get written to the stream
*/
public ProgressNotifyingInputStream(InputStream stream, int totalSize) {
if(stream==null) {
throw new NullPointerException();
}
if(totalSize == 0) {
throw new IllegalArgumentException("totalSize argument cannot be zero");
}
this.wrappedStream = stream;
this.totalSize = totalSize;
}
@Override
public int read() throws IOException {
count++;
return wrappedStream.read();
}
/**
* Get progress from 0 to 100
* @return
*/
public int getProgress() {
return count * 100 / totalSize;
}
}
@Override
protected void onPostExecute(String result) {
String resultString = null;
if (MainActivity.isDebugMode){
Log.d(TAG, "Async result: "+result);
}
boolean successful = false;
String[] errorMessages = null;
try {
JSONObject mainObject = new JSONObject(result);
String resultJsonString = mainObject.getString("result");
JSONArray messagesJsonArray = mainObject.getJSONArray("messages");
if (resultJsonString != null){
if (resultJsonString.equalsIgnoreCase("success")){
successful = true;
} else {
Log.e(TAG, "result was: "+resultJsonString);
}
}
errorMessages = new String[messagesJsonArray.length()];
for (int i = 0; i < messagesJsonArray.length(); i++){
errorMessages[i]= (String)messagesJsonArray.get(i);
}
} catch (JSONException e){
Log.e(TAG, "JSON Exception -- The string that I tried to parse was:\n"+result);
e.printStackTrace();
}
if (successful) {
Toast.makeText(this.activity, "Upload completed successfully!", Toast.LENGTH_SHORT).show();
resultString = "Upload complete.";
} else {
String eMessages;
if (errorMessages != null && errorMessages.length > 0){
eMessages = TextUtils.join(", ", errorMessages);
resultString = "Image upload failed:\n"+eMessages;
} else {
resultString = "Image upload failed!";
}
}
((ImageUploadActivity) activity).updateProgress(null);
((ImageUploadActivity) activity).setPostResult(resultString);
}
我写了一个具体的例子来说明如何做到这一点->我需要图像的上传进度,但由于实现问题(无法通过渐变和依赖错误获取包),我没有使用HttpMultipartClient。
我遇到的另一个问题是获取我想要上传的图像的实际文件大小
我的要求还包括在通知区上载。以下是我的解决方案:
获取图像大小
AsyncHttpPostTask#doInBackground
正如我前面提到的,我没有使用HttpMultipartClient
,所以我必须实现我自己的
AsyncHttpPostTask#onPostExecute
在这里,我解析服务器的JSON响应,查看上传是否能够成功处理,然后向控制通知的活动返回一条消息
package com.hyves.android.service.upload;
import java.io.IOException;
import java.io.InputStream;
/**
* This outputstream wraps an existing outputstream and provides
* callbacks after certain amount of bytes to a HttpCallback
*
* @author tjerk
*/
public class ProgressNotifyingInputStream extends InputStream {
private InputStream wrappedStream;
private int count = 0;
private int totalSize;
/**
* Creates a new notifying outputstream which wraps an existing one.
* When you write to this stream the callback will be notified each time when
* updateAfterNumberBytes is written.
*
* @param stream the outputstream to be wrapped
* @param totalSize the totalsize that will get written to the stream
*/
public ProgressNotifyingInputStream(InputStream stream, int totalSize) {
if(stream==null) {
throw new NullPointerException();
}
if(totalSize == 0) {
throw new IllegalArgumentException("totalSize argument cannot be zero");
}
this.wrappedStream = stream;
this.totalSize = totalSize;
}
@Override
public int read() throws IOException {
count++;
return wrappedStream.read();
}
/**
* Get progress from 0 to 100
* @return
*/
public int getProgress() {
return count * 100 / totalSize;
}
}
@Override
protected void onPostExecute(String result) {
String resultString = null;
if (MainActivity.isDebugMode){
Log.d(TAG, "Async result: "+result);
}
boolean successful = false;
String[] errorMessages = null;
try {
JSONObject mainObject = new JSONObject(result);
String resultJsonString = mainObject.getString("result");
JSONArray messagesJsonArray = mainObject.getJSONArray("messages");
if (resultJsonString != null){
if (resultJsonString.equalsIgnoreCase("success")){
successful = true;
} else {
Log.e(TAG, "result was: "+resultJsonString);
}
}
errorMessages = new String[messagesJsonArray.length()];
for (int i = 0; i < messagesJsonArray.length(); i++){
errorMessages[i]= (String)messagesJsonArray.get(i);
}
} catch (JSONException e){
Log.e(TAG, "JSON Exception -- The string that I tried to parse was:\n"+result);
e.printStackTrace();
}
if (successful) {
Toast.makeText(this.activity, "Upload completed successfully!", Toast.LENGTH_SHORT).show();
resultString = "Upload complete.";
} else {
String eMessages;
if (errorMessages != null && errorMessages.length > 0){
eMessages = TextUtils.join(", ", errorMessages);
resultString = "Image upload failed:\n"+eMessages;
} else {
resultString = "Image upload failed!";
}
}
((ImageUploadActivity) activity).updateProgress(null);
((ImageUploadActivity) activity).setPostResult(resultString);
}
ImageUploadActivity#updateProgress
此方法将进度刷新到通知以及活动中包含的UI
public void updateProgress(Integer progress){
this.currentProgress = progress;
if (uploadStatusTV != null && this.currentProgress != null){
currentStatus = "uploading image: "+this.currentProgress+"%";
uploadStatusTV.setText("uploading image: "+this.currentProgress+"%");
if (mBuilder == null){
buildNotify();
}
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate" state
mBuilder.setProgress(100, currentProgress, false);
// Displays the progress bar for the first time.
mNotifyManager.notify(notify_id, mBuilder.build());
} else if (uploadStatusTV != null){
return;
} else {
Log.e(TAG, "You should never see this message.");
finish();
}
}
这将显示一组图像的进度…而不是单个图像。我刚刚发现另一个博客对此进行了解释:上面指向HttpMultipartClient的链接已无效。它也位于此处:这似乎与HttpUrlConnection文档相关:为了获得最佳性能,您应该调用setFixedLengthStreamingMode(int)当正文长度事先已知时,或当正文长度未知时,设置ChunkedStreamingMode(int)。否则,HttpURLConnection将被迫在传输前将完整的请求正文缓冲在内存中,从而造成浪费(可能会耗尽)堆和增加延迟。不幸的是,Gingerbread之前的Android上存在一个错误,这意味着setFixedLengthStreamingMode无法按文档所述工作,导致所有连接都被缓冲。请检查以下答案,它可能会有所帮助:[[1]:
private void buildNotify(){
Intent resultIntent = new Intent(this, ImageUploadActivity.class);
// Because clicking the notification opens a new ("special") activity, there's
// no need to create an artificial back stack.
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mNotifyManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setContentTitle("Image Upload")
.setContentText("Image upload in progress")
.setSmallIcon(android.R.drawable.ic_menu_upload);
}
public void updateProgress(Integer progress){
this.currentProgress = progress;
if (uploadStatusTV != null && this.currentProgress != null){
currentStatus = "uploading image: "+this.currentProgress+"%";
uploadStatusTV.setText("uploading image: "+this.currentProgress+"%");
if (mBuilder == null){
buildNotify();
}
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate" state
mBuilder.setProgress(100, currentProgress, false);
// Displays the progress bar for the first time.
mNotifyManager.notify(notify_id, mBuilder.build());
} else if (uploadStatusTV != null){
return;
} else {
Log.e(TAG, "You should never see this message.");
finish();
}
}