Android上传文件到服务器,通常采用构造http协议的方法,模拟网页POST方法传输文件,服务器端可以采用JavaServlet或者PHP来 接收要传输的文件。使用JavaServlet来接收文件的方法比较常见,在这里给大家介绍一个简单的服务器端使用PHP语言来接收文件的例子。
服务器端代码比较简单,接收传输过来的文件:
2 |
$target_path = "./upload/" ; |
3 |
$target_path = $target_path . basename ( $_FILES [ 'uploadedfile' ][ 'name' ]); |
4 |
if (move_uploaded_file( $_FILES [ 'uploadedfile' ][ 'tmp_name' ], $target_path ))
{ |
5 |
echo "The
file " . basename ( $_FILES [ 'uploadedfile' ][ 'name' ]). "
has been uploaded" ; |
7 |
echo "There
was an error uploading the file, please try again!" . $_FILES [ 'uploadedfile' ][ 'error' ]; |
手机客户端代码:
001 |
package com.figo.uploadfile; |
003 |
import java.io.BufferedReader; |
004 |
import java.io.DataOutputStream; |
005 |
import java.io.FileInputStream; |
006 |
import java.io.InputStream; |
007 |
import java.io.InputStreamReader; |
008 |
import java.net.HttpURLConnection; |
010 |
import android.app.Activity; |
011 |
import android.os.Bundle; |
012 |
import android.view.View; |
013 |
import android.widget.Button; |
014 |
import android.widget.TextView; |
015 |
import android.widget.Toast; |
017 |
public class UploadfileActivity extends Activity |
020 |
private String
uploadFile = "/sdcard/testimg.jpg" ; |
021 |
private String
srcPath = "/sdcard/testimg.jpg" ; |
023 |
private String
actionUrl = "http://10.100.1.208/receive_file.php" ; |
024 |
private TextView
mText1; |
025 |
private TextView
mText2; |
026 |
private Button
mButton; |
029 |
public void onCreate(Bundle
savedInstanceState) |
031 |
super .onCreate(savedInstanceState); |
032 |
setContentView(R.layout.main); |
034 |
mText1
= (TextView) findViewById(R.id.myText2); |
035 |
mText1.setText( "文件路径:\n" +
uploadFile); |
036 |
mText2
= (TextView) findViewById(R.id.myText3); |
037 |
mText2.setText( "上传网址:\n" +
actionUrl); |
051 |
private void uploadFile(String
uploadUrl) |
054 |
String
twoHyphens = "--" ; |
055 |
String
boundary = "******" ; |
058 |
URL
url = new URL(uploadUrl); |
059 |
HttpURLConnection
httpURLConnection = (HttpURLConnection) url |
063 |
httpURLConnection.setChunkedStreamingMode( 128 * 1024 ); |
065 |
httpURLConnection.setDoInput( true ); |
066 |
httpURLConnection.setDoOutput( true ); |
067 |
httpURLConnection.setUseCaches( false ); |
069 |
httpURLConnection.setRequestMethod( "POST" ); |
070 |
httpURLConnection.setRequestProperty( "Connection" , "Keep-Alive" ); |
071 |
httpURLConnection.setRequestProperty( "Charset" , "UTF-8" ); |
072 |
httpURLConnection.setRequestProperty( "Content-Type" , |
073 |
"multipart/form-data;boundary=" +
boundary); |
075 |
DataOutputStream
dos = new DataOutputStream( |
076 |
httpURLConnection.getOutputStream()); |
077 |
dos.writeBytes(twoHyphens
+ boundary + end); |
078 |
dos.writeBytes( "Content-Disposition:
form-data; name=\"uploadedfile\"; filename=\"" |
079 |
+
srcPath.substring(srcPath.lastIndexOf( "/" )
+ 1 ) |
084 |
FileInputStream
fis = new FileInputStream(srcPath); |
085 |
byte []
buffer = new byte [ 8192 ]; |
088 |
while ((count
= fis.read(buffer)) != - 1 ) |
090 |
dos.write(buffer, 0 ,
count); |
095 |
dos.writeBytes(twoHyphens
+ boundary + twoHyphens + end); |
098 |
InputStream
is = httpURLConnection.getInputStream(); |
099 |
InputStreamReader
isr = new InputStreamReader(is, "utf-8" ); |
100 |
BufferedReader
br = new BufferedReader(isr); |
101 |
String
result = br.readLine(); |
103 |
Toast.makeText( this ,
result, Toast.LENGTH_LONG).show(); |
107 |
} catch (Exception
e) |
110 |
setTitle(e.getMessage()); |
在AndroidManifest.xml文件里添加网络访问权限:
1 |
< uses-permission android:name = "android.permission.INTERNET" /> |
运行结果:

以上已经能够实现文件上传,但没有上传进度。这次在之前的基础上添加进度显示,Java代码如下所示:
001 |
package com.lenovo.uptest; |
003 |
import java.io.DataInputStream; |
004 |
import java.io.DataOutputStream; |
006 |
import java.io.FileInputStream; |
007 |
import java.net.HttpURLConnection; |
010 |
import android.app.Activity; |
011 |
import android.app.AlertDialog; |
012 |
import android.app.ProgressDialog; |
013 |
import android.content.DialogInterface; |
014 |
import android.os.AsyncTask; |
015 |
import android.os.Bundle; |
016 |
import android.view.View; |
017 |
import android.widget.Button; |
018 |
import android.widget.TextView; |
020 |
public class UploadtestActivity extends Activity
{ |
021 |
/**
Called when the activity is first created. */ |
023 |
*
Upload file to web server with progress status, client: android; |
027 |
private TextView
mtv1 = null ; |
028 |
private TextView
mtv2 = null ; |
029 |
private Button
bupload = null ; |
031 |
private String
uploadFile = "/sdcard/testimg.jpg" ; |
032 |
private String
actionUrl = "http://10.100.1.208/receive_file.php" ; |
035 |
public void onCreate(Bundle
savedInstanceState) { |
036 |
super .onCreate(savedInstanceState); |
037 |
setContentView(R.layout.main); |
039 |
mtv1
= (TextView) findViewById(R.id.mtv1); |
040 |
mtv1.setText( "文件路径:\n" +
uploadFile); |
041 |
mtv2
= (TextView) findViewById(R.id.mtv2); |
042 |
mtv2.setText( "上传地址:\n" +
actionUrl); |
043 |
bupload
= (Button) findViewById(R.id.bupload); |
044 |
bupload.setOnClickListener( new View.OnClickListener()
{ |
047 |
public void onClick(View
v) { |
049 |
FileUploadTask
fileuploadtask = new FileUploadTask(); |
050 |
fileuploadtask.execute(); |
056 |
private void showDialog(String
mess) { |
057 |
new AlertDialog.Builder(UploadtestActivity. this ).setTitle( "Message" ) |
059 |
.setNegativeButton( "确定" , new DialogInterface.OnClickListener()
{ |
061 |
public void onClick(DialogInterface
dialog, int which)
{ |
066 |
class FileUploadTask extends AsyncTask<Object,
Integer, Void> { |
068 |
private ProgressDialog
dialog = null ; |
069 |
HttpURLConnection
connection = null ; |
070 |
DataOutputStream
outputStream = null ; |
071 |
DataInputStream
inputStream = null ; |
073 |
String
pathToOurFile = "/sdcard/testimg.jpg" ; |
075 |
String
urlServer = "http://10.100.1.208/receive_file.php" ; |
076 |
String
lineEnd = "\r\n" ; |
077 |
String
twoHyphens = "--" ; |
078 |
String
boundary = "*****" ; |
080 |
File
uploadFile = new File(pathToOurFile); |
081 |
long totalSize
= uploadFile.length(); |
084 |
protected void onPreExecute()
{ |
085 |
dialog
= new ProgressDialog(UploadtestActivity. this ); |
086 |
dialog.setMessage( "正在上传..." ); |
087 |
dialog.setIndeterminate( false ); |
088 |
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); |
089 |
dialog.setProgress( 0 ); |
094 |
protected Void
doInBackground(Object... arg0) { |
098 |
int bytesRead,
bytesAvailable, bufferSize; |
100 |
int maxBufferSize
= 256 * 1024 ; |
103 |
FileInputStream
fileInputStream = new FileInputStream( new File( |
106 |
URL
url = new URL(urlServer); |
107 |
connection
= (HttpURLConnection) url.openConnection(); |
110 |
connection.setChunkedStreamingMode( 256 * 1024 ); |
113 |
connection.setDoInput( true ); |
114 |
connection.setDoOutput( true ); |
115 |
connection.setUseCaches( false ); |
118 |
connection.setRequestMethod( "POST" ); |
119 |
connection.setRequestProperty( "Connection" , "Keep-Alive" ); |
120 |
connection.setRequestProperty( "Charset" , "UTF-8" ); |
121 |
connection.setRequestProperty( "Content-Type" , |
122 |
"multipart/form-data;boundary=" +
boundary); |
124 |
outputStream
= new DataOutputStream( |
125 |
connection.getOutputStream()); |
126 |
outputStream.writeBytes(twoHyphens
+ boundary + lineEnd); |
128 |
.writeBytes( "Content-Disposition:
form-data; name=\"uploadedfile\";filename=\"" |
129 |
+
pathToOurFile + "\"" +
lineEnd); |
130 |
outputStream.writeBytes(lineEnd); |
132 |
bytesAvailable
= fileInputStream.available(); |
133 |
bufferSize
= Math.min(bytesAvailable, maxBufferSize); |
134 |
buffer
= new byte [bufferSize]; |
137 |
bytesRead
= fileInputStream.read(buffer, 0 ,
bufferSize); |
139 |
while (bytesRead
> 0 )
{ |
140 |
outputStream.write(buffer, 0 ,
bufferSize); |
141 |
length
+= bufferSize; |
142 |
progress
= ( int )
((length * 100 )
/ totalSize); |
143 |
publishProgress(progress); |
145 |
bytesAvailable
= fileInputStream.available(); |
146 |
bufferSize
= Math.min(bytesAvailable, maxBufferSize); |
147 |
bytesRead
= fileInputStream.read(buffer, 0 ,
bufferSize); |
149 |
outputStream.writeBytes(lineEnd); |
150 |
outputStream.writeBytes(twoHyphens
+ boundary + twoHyphens |
152 |
publishProgress( 100 ); |
155 |
int serverResponseCode
= connection.getResponseCode(); |
156 |
String
serverResponseMessage = connection.getResponseMessage(); |
173 |
fileInputStream.close(); |
174 |
outputStream.flush(); |
175 |
outputStream.close(); |
177 |
} catch (Exception
ex) { |
189 |
protected void onProgressUpdate(Integer...
progress) { |
190 |
dialog.setProgress(progress[ 0 ]); |
194 |
protected void onPostExecute(Void
result) { |
198 |
} catch (Exception
e) { |
服务器端仍然和之前的一样。
这里使用了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传入的参数。
运行结果如下:
