Android上使用camera拍照,把获取的照片上传到远程服务器
jopen
10年前
使用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(); } }
代码
https://github.com/DynamsoftRD/JavaHTTPUpload
Git clone https://github.com/DynamsoftRD/JavaHTTPUpload.git