使用Java上传文件
从Apache Software Foundation下载HttpClient 4.3.4。
在工程中添加下面的jar包:
参考sample,写一个简单的上传:
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("http://localhost:8003/savetofile.php"); // your server
FileBody bin = new FileBody(new File("my.jpg")); // image for uploading
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("myFile", bin)
.build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
Android上拍照
Camera的使用很简单,只需要参考开发者网站的这篇Taking Photos Simply。
调用系统camera只需要如下代码:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
拍照之后,camera会返回缩略图:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0 && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
如果要获得高质量的图,就需要指定照片的保存路径。在AndroidManifest.xml中添加下面的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
修改调用方法:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
Intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(intent, 0);
拍照之后,使用预设的图片路径解码,就可以获取高质量的图:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0 && resultCode == Activity.RESULT_OK) {
setPic();
}
}
private void setPic() {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}
从Android客户端传送图片到PHP服务器
要访问Internet,在AndroidManifest.xml中添加访问权限:
<uses-permission android:name="android.permission.INTERNET"/>
参考http://blog.rafaelsanches.com/2011/01/29/upload-using-multipart-post-using-httpclient-in-android/,创建一个类MultipartEntity:
public class MultipartEntity implements HttpEntity {
private String boundary = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
boolean isSetLast = false;
boolean isSetFirst = false;
public MultipartEntity() {
this.boundary = System.currentTimeMillis() + "";
}
public void writeFirstBoundaryIfNeeds(){
if(!isSetFirst){
try {
out.write(("--" + boundary + "\r\n").getBytes());
} catch (final IOException e) {
}
}
isSetFirst = true;
}
public void writeLastBoundaryIfNeeds() {
if(isSetLast){
return ;
}
try {
out.write(("\r\n--" + boundary + "--\r\n").getBytes());
} catch (final IOException e) {
}
isSetLast = true;
}
public void addPart(final String key, final String value) {
writeFirstBoundaryIfNeeds();
try {
out.write(("Content-Disposition: form-data; name=\"" +key+"\"\r\n").getBytes());
out.write("Content-Type: text/plain; charset=UTF-8\r\n".getBytes());
out.write("Content-Transfer-Encoding: 8bit\r\n\r\n".getBytes());
out.write(value.getBytes());
out.write(("\r\n--" + boundary + "\r\n").getBytes());
} catch (final IOException e) {
}
}
public void addPart(final String key, final String fileName, final InputStream fin){
addPart(key, fileName, fin, "application/octet-stream");
}
public void addPart(final String key, final String fileName, final InputStream fin, String type){
writeFirstBoundaryIfNeeds();
try {
type = "Content-Type: "+type+"\r\n";
out.write(("Content-Disposition: form-data; name=\""+ key+"\"; filename=\"" + fileName + "\"\r\n").getBytes());
out.write(type.getBytes());
out.write("Content-Transfer-Encoding: binary\r\n\r\n".getBytes());
final byte[] tmp = new byte[4096];
int l = 0;
while ((l = fin.read(tmp)) != -1) {
out.write(tmp, 0, l);
}
out.flush();
} catch (final IOException e) {
} finally {
try {
fin.close();
} catch (final IOException e) {
}
}
}
public void addPart(final String key, final File value) {
try {
addPart(key, value.getName(), new FileInputStream(value));
} catch (final FileNotFoundException e) {
}
}
@Override
public long getContentLength() {
writeLastBoundaryIfNeeds();
return out.toByteArray().length;
}
@Override
public Header getContentType() {
return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
}
@Override
public boolean isChunked() {
return false;
}
@Override
public boolean isRepeatable() {
return false;
}
@Override
public boolean isStreaming() {
return false;
}
@Override
public void writeTo(final OutputStream outstream) throws IOException {
outstream.write(out.toByteArray());
}
@Override
public Header getContentEncoding() {
return null;
}
@Override
public void consumeContent() throws IOException,
UnsupportedOperationException {
if (isStreaming()) {
throw new UnsupportedOperationException(
"Streaming entity does not implement #consumeContent()");
}
}
@Override
public InputStream getContent() throws IOException,
UnsupportedOperationException {
return new ByteArrayInputStream(out.toByteArray());
}
}
使用AsyncTask来完成上传:
private class UploadTask extends AsyncTask<Bitmap, Void, Void> {
protected Void doInBackground(Bitmap... bitmaps) {
if (bitmaps[0] == null)
return null;
Bitmap bitmap = bitmaps[0];
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); // convert Bitmap to ByteArrayOutputStream
InputStream in = new ByteArrayInputStream(stream.toByteArray()); // convert ByteArrayOutputStream to ByteArrayInputStream
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost(
"http://192.168.8.84:8003/savetofile.php"); // server
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("myFile",
System.currentTimeMillis() + ".jpg", in);
httppost.setEntity(reqEntity);
Log.i(TAG, "request " + httppost.getRequestLine());
HttpResponse response = null;
try {
response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (response != null)
Log.i(TAG, "response " + response.getStatusLine().toString());
} finally {
}
} finally {
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Toast.makeText(MainActivity.this, R.string.uploaded, Toast.LENGTH_LONG).show();
}
}