android文件上传可能是一个比较耗时的操作,如果为上传操作带上进度提示则可以更好的提高用户体验,最后效果如下图:
项目源码:http://download.csdn.net/detail/shinay/4965230
注意:此方法可能已经实现,推荐引用开源框架通过AsyncHttpClient进行文件上传:http://blog.csdn.net/jdsjlzx/article/details/41694323
这里只贴出代码,可根据实际情况自行修改。
- package com.lxb.uploadwithprogress.http;
-
- import java.io.File;
-
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.mime.content.FileBody;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.protocol.BasicHttpContext;
- import org.apache.http.protocol.HttpContext;
- import org.apache.http.util.EntityUtils;
-
- import android.app.ProgressDialog;
- import android.content.Context;
- import android.os.AsyncTask;
-
- import com.lxb.uploadwithprogress.http.CustomMultipartEntity.ProgressListener;
-
- public class HttpMultipartPost extends AsyncTask<String, Integer, String> {
-
- private Context context;
- private String filePath;
- private ProgressDialog pd;
- private long totalSize;
-
- public HttpMultipartPost(Context context, String filePath) {
- this.context = context;
- this.filePath = filePath;
- }
-
- @Override
- protected void onPreExecute() {
- pd = new ProgressDialog(context);
- pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- pd.setMessage("Uploading Picture...");
- pd.setCancelable(false);
- pd.show();
- }
-
- @Override
- protected String doInBackground(String... params) {
- String serverResponse = null;
-
- HttpClient httpClient = new DefaultHttpClient();
- HttpContext httpContext = new BasicHttpContext();
- HttpPost httpPost = new HttpPost("上传URL, 如:http://www.xx.com/upload.php");
-
- try {
- CustomMultipartEntity multipartContent = new CustomMultipartEntity(
- new ProgressListener() {
- @Override
- public void transferred(long num) {
- publishProgress((int) ((num / (float) totalSize) * 100));
- }
- });
-
-
- multipartContent.addPart("data", new FileBody(new File(
- filePath)));
- totalSize = multipartContent.getContentLength();
-
-
- httpPost.setEntity(multipartContent);
- HttpResponse response = httpClient.execute(httpPost, httpContext);
- serverResponse = EntityUtils.toString(response.getEntity());
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return serverResponse;
- }
-
- @Override
- protected void onProgressUpdate(Integer... progress) {
- pd.setProgress((int) (progress[0]));
- }
-
- @Override
- protected void onPostExecute(String result) {
- System.out.println("result: " + result);
- pd.dismiss();
- }
-
- @Override
- protected void onCancelled() {
- System.out.println("cancle");
- }
-
- }
- package com.lxb.uploadwithprogress.http;
-
- import java.io.FilterOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.charset.Charset;
-
- import org.apache.http.entity.mime.HttpMultipartMode;
- import org.apache.http.entity.mime.MultipartEntity;
-
- public class CustomMultipartEntity extends MultipartEntity {
-
- private final ProgressListener listener;
-
- public CustomMultipartEntity(final ProgressListener listener) {
- super();
- this.listener = listener;
- }
-
- public CustomMultipartEntity(final HttpMultipartMode mode,
- final ProgressListener listener) {
- super(mode);
- this.listener = listener;
- }
-
- public CustomMultipartEntity(HttpMultipartMode mode, final String boundary,
- final Charset charset, final ProgressListener listener) {
- super(mode, boundary, charset);
- this.listener = listener;
- }
-
- @Override
- public void writeTo(OutputStream outstream) throws IOException {
- super.writeTo(new CountingOutputStream(outstream, this.listener));
- }
-
- public static interface ProgressListener {
- void transferred(long num);
- }
-
- public static class CountingOutputStream extends FilterOutputStream {
-
- private final ProgressListener listener;
- private long transferred;
-
- public CountingOutputStream(final OutputStream out,
- final ProgressListener listener) {
- super(out);
- this.listener = listener;
- this.transferred = 0;
- }
-
- public void write(byte[] b, int off, int len) throws IOException {
- out.write(b, off, len);
- this.transferred += len;
- this.listener.transferred(this.transferred);
- }
-
- public void write(int b) throws IOException {
- out.write(b);
- this.transferred++;
- this.listener.transferred(this.transferred);
- }
- }
-
- }
上面为两个主要的类,下面放一个调用的Activity
- package com.lxb.uploadwithprogress;
-
- import java.io.File;
-
- import com.lxb.uploadwithprogress.http.HttpMultipartPost;
-
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.Toast;
-
- public class MainActivity extends Activity implements OnClickListener {
-
- private Context context;
-
- private EditText et_filepath;
- private Button btn_upload;
- private Button btn_cancle;
-
- private HttpMultipartPost post;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- context = this;
-
- setContentView(R.layout.activity_main);
-
- et_filepath = (EditText) findViewById(R.id.et_filepath);
- btn_upload = (Button) findViewById(R.id.btn_upload);
- btn_cancle = (Button) findViewById(R.id.btn_cancle);
-
- btn_upload.setOnClickListener(this);
- btn_cancle.setOnClickListener(this);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn_upload:
- String filePath = et_filepath.getText().toString();
- File file = new File(filePath);
- if (file.exists()) {
- post = new HttpMultipartPost(context, filePath);
- post.execute();
- } else {
- Toast.makeText(context, "file not exists", Toast.LENGTH_LONG).show();
- }
- break;
- case R.id.btn_cancle:
- if (post != null) {
- if (!post.isCancelled()) {
- post.cancel(true);
- }
- }
- break;
- }
-
- }
-
- }
当然,在Android中使用MultipartEntity类,必须为项目增加相应的jar包,httpmime-4.1.2.jar。
最后放上代码,工程里已包含jar。
地址:
http://download.csdn.net/detail/shinay/4965230
Android 下载文件 进度条显示
http://blog.csdn.net/rwyz1314/article/details/6798222
加入两个权限
一个是联网,另一个是读写SD卡
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
下载地址是本人的另外一台主机,现在当服务器了,路径可以测试
http://210.30.12.1:8080/mp3/DJ.mp3
android自定义Dialog实现文件下载和下载进度
http://blog.csdn.net/vipa1888/article/details/7459200
最近要实现一个检验更新的功能,当进入程序的时候,开始请求服务器,然后得到服务器的响应更新结果!如果需要更新的话,就打开一个Dialog,在Dialog上面下载文件,于是自己研究了一个自定义dialog的实现,也完成了在dialog上面有进度的下载文件(自己的作图技术查,随便画了一个背景),效果图如下:
效果如上,下面我把代码贴出来:
主界面Activity: 主界面就定义了一个Button,当点击Button后,弹出Dialog
- package com.spring.sky.dialog.download;
-
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.ImageView;
-
- /**
- * 主界面
- * @author spring sky
- */
- public class MainActivity extends Activity implements
- android.view.View.OnClickListener {
- private Button bt;
- private ImageView imageView;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- init();
- }
-
- private void init() {
- bt = (Button) this.findViewById(R.id.bt);
- bt.setOnClickListener(this);
- imageView = (ImageView) findViewById(R.id.imageview);
- }
-
- @Override
- public void onClick(View v) {
- DownloadDialog dialog = new DownloadDialog(this,
- "http://img308.ph.126.net/AM2zg9CNx0kG8K3jY122RQ==/3902932027070067384.jpg");
- dialog.setImageView(imageView); //当前下载的是一个图片,所以下载完成后,把这个图片显示在界面上
- dialog.show();
- }
- }
main.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
-
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
-
- <Button
- android:id="@+id/bt"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="弹出框下载文件" />
-
- <ImageView
- android:id="@+id/imageview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- />
- </LinearLayout>
-
- </ScrollView>
自定义的Dialog : 这个基本就是实现Dialog的布局,还有Dialog的背景透明效果,然后用户点击了下载,启动一个新线程下载,同时用handler来发送消息,让下载操作的进度在Dialog的view上面呈现出来,当下载完成的时候,点击按钮就可以看见下载的图片了! (我测试为了简单就用了一个ImageView把图片显示出来)
- package com.spring.sky.dialog.download;
-
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.net.URL;
- import java.net.URLConnection;
-
-
- import android.app.Dialog;
- import android.content.Context;
- import android.graphics.BitmapFactory;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import android.widget.Toast;
-
-
-
-
-
-
- public class DownloadDialog extends Dialog implements
- android.view.View.OnClickListener {
- private static final int DOWNLOAD_PREPARE = 0;
- private static final int DOWNLOAD_WORK = 1;
- private static final int DOWNLOAD_OK = 2;
- private static final int DOWNLOAD_ERROR = 3;
- private static final String TAG = "IndexActivity";
- private Context mContext;
-
- private Button bt;
- private ProgressBar pb;
-
- private boolean isClick = false;
- private boolean downloadOk = false;
- private TextView tv;
-
-
-
- private String url = null;
- private String filePath;
-
-
-
-
- int fileSize = 0;
-
-
-
-
- int downloadSize = 0;
-
-
-
-
- private Handler handler = new Handler() {
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case DOWNLOAD_PREPARE:
- Toast.makeText(mContext, "准备下载", Toast.LENGTH_SHORT).show();
- pb.setVisibility(ProgressBar.VISIBLE);
- Log.e(TAG, "文件大小:" + fileSize);
- pb.setMax(fileSize);
- break;
- case DOWNLOAD_WORK:
- Log.e(TAG, "已经下载:" + downloadSize);
- pb.setProgress(downloadSize);
- int res = downloadSize * 100 / fileSize;
- tv.setText("已下载:" + res + "%");
- bt.setText(FileUtil.FormetFileSize(downloadSize) + "/"
- + FileUtil.FormetFileSize(fileSize));
- break;
- case DOWNLOAD_OK:
- downloadOk = true;
- bt.setText("下载完成显示图片");
- downloadSize = 0;
- fileSize = 0;
- Toast.makeText(mContext, "下载成功", Toast.LENGTH_SHORT).show();
- break;
- case DOWNLOAD_ERROR:
- downloadSize = 0;
- fileSize = 0;
- Toast.makeText(mContext, "下载失败", Toast.LENGTH_SHORT).show();
- break;
- }
- super.handleMessage(msg);
- }
- };
-
- private ImageView imageView;
-
- public DownloadDialog(Context context, String url) {
-
- super(context, R.style.Theme_CustomDialog);
- mContext = context;
- this.url = url;
- filePath = FileUtil.getPath(mContext, url);
- }
-
- @Override
- public void cancel() {
- super.cancel();
- }
-
-
-
-
- private void downloadFile() {
- try {
- URL u = new URL(url);
- URLConnection conn = u.openConnection();
- InputStream is = conn.getInputStream();
- fileSize = conn.getContentLength();
- if (fileSize < 1 || is == null) {
- sendMessage(DOWNLOAD_ERROR);
- } else {
- sendMessage(DOWNLOAD_PREPARE);
- FileOutputStream fos = new FileOutputStream(filePath);
- byte[] bytes = new byte[1024];
- int len = -1;
- while ((len = is.read(bytes)) != -1) {
- fos.write(bytes, 0, len);
- fos.flush();
- downloadSize += len;
- sendMessage(DOWNLOAD_WORK);
- }
- sendMessage(DOWNLOAD_OK);
- is.close();
- fos.close();
- }
- } catch (Exception e) {
- sendMessage(DOWNLOAD_ERROR);
- e.printStackTrace();
- }
- }
-
-
-
-
-
- public String getFilePath() {
- return filePath;
- }
- private void init() {
- bt = (Button) this.findViewById(R.id.down_bt);
- bt.setOnClickListener(this);
- tv = (TextView) this.findViewById(R.id.down_tv);
- pb = (ProgressBar) this.findViewById(R.id.down_pb);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.down_bt:
- if (isClick) {
-
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- downloadFile();
- }
- });
- thread.start();
- isClick = false;
- }
-
- if (downloadOk)
- {
- imageView.setImageBitmap(BitmapFactory.decodeFile(filePath));
- cancel();
- }
- break;
- default:
- break;
- }
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.download_layuot);
- init();
- }
-
-
-
-
- private void sendMessage(int what) {
- Message m = new Message();
- m.what = what;
- handler.sendMessage(m);
- }
-
- public void setImageView(ImageView imageView) {
- this.imageView = imageView;
- }
-
- @Override
- public void show() {
- isClick = true;
- downloadOk = false;
- super.show();
- }
-
- }
dialog的download_layuot.xml布局文件: 这个使用了相对布局,让ProgressBar和TextView呈现在一个居中位置,看起来就像连在一起的效果!同时Button来实现文件大小的显示
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/dialog"
- android:orientation="vertical" >
- <TextView
- android:layout_margin="5dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:text="有新的版本更新"
- android:textSize="20dip"
- android:textColor="@android:color/white" />
-
- <RelativeLayout
- android:layout_margin="10dip"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- >
- <ProgressBar
- android:layout_centerHorizontal="true"
- android:layout_centerVertical="true"
- android:id="@+id/down_pb"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="260dip"
- android:layout_height="wrap_content"
- />
- <TextView
- android:layout_centerHorizontal="true"
- android:layout_centerVertical="true"
- android:id="@+id/down_tv"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="开始下载..."
- android:textColor="@android:color/white"
- android:textSize="20sp" />
- </RelativeLayout>
- <Button
- android:layout_gravity="center_horizontal"
- android:id="@+id/down_bt"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:text="点击下载"
- android:textColor="@android:color/black"
- android:textSize="16sp"
- android:layout_marginTop="10dip"
- android:layout_marginBottom="10dip" />
- </LinearLayout>
在dialog中需要一个样式,这个样式可以实现Dialog后面的背景透明:
- <?xml version="1.0" encoding="utf-8"?>
-
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <stroke android:width="3dp"/>
- <corners android:radius="3dp" />
- <padding android:left="10dp" android:top="10dp"
- android:right="10dp" android:bottom="10dp" />
- <solid android:color="@android:color/transparent"/>
- </shape>
还有一个FileUtil.java的文件工具类: