Android上传文件到Web服务器,PHP接收文件(二)
接上一篇文章《Android上传文件到Web服务器,PHP接收文件(一)》,这次在之前的基础上添加进度显示,Java代码如下所示:
[java]view plaincopy- packagecom.lenovo.uptest;
- importjava.io.DataInputStream;
- importjava.io.DataOutputStream;
- importjava.io.File;
- importjava.io.FileInputStream;
- importjava.net.HttpURLConnection;
- importjava.net.URL;
- importandroid.app.Activity;
- importandroid.app.AlertDialog;
- importandroid.app.ProgressDialog;
- importandroid.content.DialogInterface;
- importandroid.os.AsyncTask;
- importandroid.os.Bundle;
- importandroid.view.View;
- importandroid.widget.Button;
- importandroid.widget.TextView;
- publicclassUploadtestActivityextendsActivity{
- /**Calledwhentheactivityisfirstcreated.*/
- /**
- *Uploadfiletowebserverwithprogressstatus,client:android;
- *server:php
- ***/
- privateTextViewmtv1=null;
- privateTextViewmtv2=null;
- privateButtonbupload=null;
- privateStringuploadFile="/sdcard/testimg.jpg";
- privateStringactionUrl="http://10.100.1.208/receive_file.php";
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mtv1=(TextView)findViewById(R.id.mtv1);
- mtv1.setText("文件路径:\n"+uploadFile);
- mtv2=(TextView)findViewById(R.id.mtv2);
- mtv2.setText("上传地址:\n"+actionUrl);
- bupload=(Button)findViewById(R.id.bupload);
- bupload.setOnClickListener(newView.OnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- //TODOAuto-generatedmethodstub
- FileUploadTaskfileuploadtask=newFileUploadTask();
- fileuploadtask.execute();
- }
- });
- }
- //showDialogmethod
- privatevoidshowDialog(Stringmess){
- newAlertDialog.Builder(UploadtestActivity.this).setTitle("Message")
- .setMessage(mess)
- .setNegativeButton("确定",newDialogInterface.OnClickListener(){
- @Override
- publicvoidonClick(DialogInterfacedialog,intwhich){
- }
- }).show();
- }
- classFileUploadTaskextendsAsyncTask<Object,Integer,Void>{
- privateProgressDialogdialog=null;
- HttpURLConnectionconnection=null;
- DataOutputStreamoutputStream=null;
- DataInputStreaminputStream=null;
- //thefilepathtoupload
- StringpathToOurFile="/sdcard/testimg.jpg";
- //theserveraddresstoprocessuploadedfile
- StringurlServer="http://10.100.1.208/receive_file.php";
- StringlineEnd="\r\n";
- StringtwoHyphens="--";
- Stringboundary="*****";
- FileuploadFile=newFile(pathToOurFile);
- longtotalSize=uploadFile.length();//Getsizeoffile,bytes
- @Override
- protectedvoidonPreExecute(){
- dialog=newProgressDialog(UploadtestActivity.this);
- dialog.setMessage("正在上传...");
- dialog.setIndeterminate(false);
- dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- dialog.setProgress(0);
- dialog.show();
- }
- @Override
- protectedVoiddoInBackground(Object...arg0){
- longlength=0;
- intprogress;
- intbytesRead,bytesAvailable,bufferSize;
- byte[]buffer;
- intmaxBufferSize=256*1024;//256KB
- try{
- FileInputStreamfileInputStream=newFileInputStream(newFile(
- pathToOurFile));
- URLurl=newURL(urlServer);
- connection=(HttpURLConnection)url.openConnection();
- //Setsizeofeveryblockforpost
- connection.setChunkedStreamingMode(256*1024);//256KB
- //AllowInputs&Outputs
- connection.setDoInput(true);
- connection.setDoOutput(true);
- connection.setUseCaches(false);
- //EnablePOSTmethod
- connection.setRequestMethod("POST");
- connection.setRequestProperty("Connection","Keep-Alive");
- connection.setRequestProperty("Charset","UTF-8");
- connection.setRequestProperty("Content-Type",
- "multipart/form-data;boundary="+boundary);
- outputStream=newDataOutputStream(
- connection.getOutputStream());
- outputStream.writeBytes(twoHyphens+boundary+lineEnd);
- outputStream
- .writeBytes("Content-Disposition:form-data;name=\"uploadedfile\";filename=\""
- +pathToOurFile+"\""+lineEnd);
- outputStream.writeBytes(lineEnd);
- bytesAvailable=fileInputStream.available();
- bufferSize=Math.min(bytesAvailable,maxBufferSize);
- buffer=newbyte[bufferSize];
- //Readfile
- bytesRead=fileInputStream.read(buffer,0,bufferSize);
- while(bytesRead>0){
- outputStream.write(buffer,0,bufferSize);
- length+=bufferSize;
- progress=(int)((length*100)/totalSize);
- publishProgress(progress);
- bytesAvailable=fileInputStream.available();
- bufferSize=Math.min(bytesAvailable,maxBufferSize);
- bytesRead=fileInputStream.read(buffer,0,bufferSize);
- }
- outputStream.writeBytes(lineEnd);
- outputStream.writeBytes(twoHyphens+boundary+twoHyphens
- +lineEnd);
- publishProgress(100);
- //Responsesfromtheserver(codeandmessage)
- intserverResponseCode=connection.getResponseCode();
- StringserverResponseMessage=connection.getResponseMessage();
- /*将Response显示于Dialog*/
- //Toasttoast=Toast.makeText(UploadtestActivity.this,""
- //+serverResponseMessage.toString().trim(),
- //Toast.LENGTH_LONG);
- //showDialog(serverResponseMessage.toString().trim());
- /*取得Response内容*/
- //InputStreamis=connection.getInputStream();
- //intch;
- //StringBuffersbf=newStringBuffer();
- //while((ch=is.read())!=-1){
- //sbf.append((char)ch);
- //}
- //
- //showDialog(sbf.toString().trim());
- fileInputStream.close();
- outputStream.flush();
- outputStream.close();
- }catch(Exceptionex){
- //Exceptionhandling
- //showDialog(""+ex);
- //Toasttoast=Toast.makeText(UploadtestActivity.this,""+
- //ex,
- //Toast.LENGTH_LONG);
- }
- returnnull;
- }
- @Override
- protectedvoidonProgressUpdate(Integer...progress){
- dialog.setProgress(progress[0]);
- }
- @Override
- protectedvoidonPostExecute(Voidresult){
- try{
- dialog.dismiss();
- //TODOAuto-generatedmethodstub
- }catch(Exceptione){
- }
- }
- }
- }
服务器端仍然和之前的一样。
这里使用了AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单,适用于简单的异步处理,不需要借助线程和Handler即可实现。
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
1) 子类化AsyncTask
2) 实现AsyncTask中定义的下面一个或几个方法
onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第三个为doInBackground返回和onPostExecute传入的参数。
运行结果如下:
更多相关文章
- Android 获取系统设置参数。
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android notification点击跳转到Activity,点击返回跳转,前一条消息
- Android:UI更新方法四:在Worker Thread中runOnUiThread直接刷新U
- Android 获取屏幕高宽度,密度,通知栏高度,截图等常用方法
- Android退出程序的多种方法
- Android数据共享 sharedPreferences 的使用方法