Android实现上传拍下的照片到服务器
作为一个玩Android的新手,之前一直在玩有关UI的东西,很少接触后端,昨天网上帮同学完成一个项目,要求实现手机调用摄像头拍照,然后预览照片最后还要讲图片上传到服务端。于是就找到了这样一个github上的文档
上传拍下的照片、视频到服务器
这个文档写的非常的清楚,代码也有,不过我这里还是想写点我的分析。
Config这个类,这个类用于保存文件上传所送到的 URL 地址,还有在移动设备中存储图片/视频的目录名称。你可能需要在测试 App 时使用你自己的 URL 地址进行上传操作。上面的链接没有给出Config 的代码,其实也不需要给出 因为这里你只需要设置你上传文件的URL的地址就好了。这里我贴出自己的代码。
public static final String FILE_UPLOAD_URL = "http://XXXXXXXXX/fileUpload.php"; // Directory name to store captured images and videos public static final String IMAGE_DIRECTORY_NAME = "Android File Upload";
FILE_UPLOAD_URL就是你连接后端服务器用的,我这里用的是php,别的行不行我就不知道了,理论上是没问题。
AndroidMultiPartEntity这个类我也没有认真的去分析它,就知道它在进度条的进度增量上有用到。
后面就是MainActivity这个类了,这个类的界面很简单按钮一个就行(因为这里我只需要拍照不需要录像),这里我也把我的代码贴上,虽然没多大区别。
import java.io.File;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;import android.app.Activity;import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.Toast;import android.view.View.OnClickListener;public class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100; private static final int MEDIA_TYPE_IMAGE = 1; private Uri fileUri; private Button btn_take,btn_load; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_take = (Button) findViewById(R.id.btn_take); btn_load= (Button) findViewById(R.id.btn_load); btn_take.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { takephoto(); } }); if(!isDeviceSupportCamera()){ Toast.makeText(getApplicationContext(), "Sorry! Your device doesn't support camera", Toast.LENGTH_LONG).show(); finish(); } } //检查设备是否有摄像机 private boolean isDeviceSupportCamera() { if (getApplicationContext().getPackageManager().hasSystemFeature( PackageManager.FEATURE_CAMERA)) { return true; } else { return false; } } private void takephoto(){ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // start the image capture Intent startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE); } public Uri getOutputMediaFileUri(int type) { return Uri.fromFile(getOutputMediaFile(type)); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { // if the result is capturing Image if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) { if (resultCode == RESULT_OK) { // successfully captured the image // launching upload activity Log.e(TAG, "I have finish it"); launchUploadActivity(true); } else if (resultCode == RESULT_CANCELED) { // user cancelled Image capture Toast.makeText(getApplicationContext(), "User cancelled image capture", Toast.LENGTH_SHORT) .show(); } else { // failed to capture image Toast.makeText(getApplicationContext(), "Sorry! Failed to capture image", Toast.LENGTH_SHORT) .show(); } } else { // failed to record video Toast.makeText(getApplicationContext(), "Sorry! Failed to record video", Toast.LENGTH_SHORT) .show(); } } private void launchUploadActivity(boolean isImage){ Intent i = new Intent(MainActivity.this, UpLoadActivity.class); i.putExtra("filePath", fileUri.getPath()); i.putExtra("isImage", isImage); startActivity(i); Log.e(TAG, "Did i have finish"); } private static File getOutputMediaFile(int type) { // External sdcard location File mediaStorageDir = new File( Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), Config.IMAGE_DIRECTORY_NAME); // Create the storage directory if it does not exist if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d(TAG, "Oops! Failed create " + Config.IMAGE_DIRECTORY_NAME + " directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); } else { return null; } return mediaFile; }}
点击按钮即调用takephoto()这个函数,这个函数就是请求手机调用摄像头的。当然别忘记在AndroidManifest.xml 中添加相应的权限 。
拍照确定 保存该照片后,程序直接跳转到UploadAcitvity
因为我们在调用摄像头的时候使用的是startActivityForResult这个函数,这个函数是在你调用摄像头这个Activity完成后去执行onActivityResult()这个函数,然后根据requestCode和resultCode两个参数决定实现某种功能,在这里若拍照成功,则返回RESULT_OK然后跳转到UploadAcitivity中去。这里我在学习下是怎么保存image的。
我们可以看到takephoto()种有一个变量fileUri,从变量名就看得出是image的路径。好,接下来就是getOutputMediaFileUri和getOutputMediaFile,getOutputMediaFileUri()函数中就只有一句代码,主要就是fromFile这个函数,这个函数的作用呢是从文件中创建一个URI。该URI的形式是“文件://”。除’/’编码路径的字符。那么getOutputMediaFile这个函数肯定是将图片以及图片的信息放到保存起来作为一个文件。
好的,最后我们进入UploadAcitvity中去,我们可以在launchUploadActivity()这个函数中看到,在我们调用UploadAcitvity时还给她传了两个参数,一个是fileUri(图片的路径),一个是isImage(判断它是否是图片)。
package com.qingfeng.imageload;import com.qingfeng.imageload.AndroidMultiPartEntity.ProgressListener;import java.io.File;import java.io.IOException;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.ClientProtocolException;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.entity.mime.content.StringBody;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.os.AsyncTask;import android.os.Bundle;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;import android.widget.VideoView;public class UploadActivity extends Activity { // LogCat tag private static final String TAG = MainActivity.class.getSimpleName(); private ProgressBar progressBar; private String filePath = null; private TextView txtPercentage; private ImageView imgPreview; private VideoView vidPreview; private Button btnUpload; long totalSize = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_upload); txtPercentage = (TextView) findViewById(R.id.txtPercentage); btnUpload = (Button) findViewById(R.id.btnUpload); progressBar = (ProgressBar) findViewById(R.id.progressBar); imgPreview = (ImageView) findViewById(R.id.imgPreview); vidPreview = (VideoView) findViewById(R.id.videoPreview); // Changing action bar background color getActionBar().setBackgroundDrawable( new ColorDrawable(Color.parseColor(getResources().getString( R.color.action_bar)))); // Receiving the data from previous activity Intent i = getIntent(); // image or video path that is captured in previous activity filePath = i.getStringExtra("filePath"); // boolean flag to identify the media type, image or video boolean isImage = i.getBooleanExtra("isImage", true); if (filePath != null) { // Displaying the image or video on the screen previewMedia(isImage); } else { Toast.makeText(getApplicationContext(), "Sorry, file path is missing!", Toast.LENGTH_LONG).show(); } btnUpload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // uploading the file to server new UploadFileToServer().execute(); } }); } /** * Displaying captured image/video on the screen * */ private void previewMedia(boolean isImage) { // Checking whether captured media is image or video if (isImage) { imgPreview.setVisibility(View.VISIBLE); vidPreview.setVisibility(View.GONE); // bimatp factory BitmapFactory.Options options = new BitmapFactory.Options(); // down sizing image as it throws OutOfMemory Exception for larger // images options.inSampleSize = 8; final Bitmap bitmap = BitmapFactory.decodeFile(filePath, options); imgPreview.setImageBitmap(bitmap); } else { imgPreview.setVisibility(View.GONE); vidPreview.setVisibility(View.VISIBLE); vidPreview.setVideoPath(filePath); // start playing vidPreview.start(); } } /** * Uploading the file to server * */ private class UploadFileToServer extends AsyncTask<Void, Integer, String> { @Override protected void onPreExecute() { // setting progress bar to zero progressBar.setProgress(0); super.onPreExecute(); } @Override protected void onProgressUpdate(Integer... progress) { // Making progress bar visible progressBar.setVisibility(View.VISIBLE); // updating progress bar value progressBar.setProgress(progress[0]); // updating percentage value txtPercentage.setText(String.valueOf(progress[0]) + "%"); } @Override protected String doInBackground(Void... params) { return uploadFile(); } @SuppressWarnings("deprecation") private String uploadFile() { String responseString = null; HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(Config.FILE_UPLOAD_URL); try { AndroidMultiPartEntity entity = new AndroidMultiPartEntity( new ProgressListener() { @Override public void transferred(long num) { publishProgress((int) ((num / (float) totalSize) * 100)); } }); File sourceFile = new File(filePath); // Adding file data to http body entity.addPart("image", new FileBody(sourceFile)); // Extra parameters if you want to pass to server entity.addPart("website", new StringBody("www.android.com")); entity.addPart("email", new StringBody("promisesaybye@gmail.com")); totalSize = entity.getContentLength(); httppost.setEntity(entity); // Making server call HttpResponse response = httpclient.execute(httppost); HttpEntity r_entity = response.getEntity(); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 200) { // Server response responseString = EntityUtils.toString(r_entity); } else { responseString = "Error occurred! Http Status Code: " + statusCode; } } catch (ClientProtocolException e) { responseString = e.toString(); } catch (IOException e) { responseString = e.toString(); } return responseString; } @Override protected void onPostExecute(String result) { Log.e(TAG, "Response from server: " + result); // showing the server response in an alert dialog showAlert(result); super.onPostExecute(result); } } /** * Method to show alert dialog * */ private void showAlert(String message) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(message).setTitle("Response from Servers") .setCancelable(false) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // do nothing } }); AlertDialog alert = builder.create(); alert.show(); }}
上面是有关UploadActivity的代码。最重要的肯定是上传到服务器的编写了—-UploadFileToServer()里面的doInBackground()这个函数中的uploadFile。里面有个addPart我去官网搜都没搜到,若有大神知道还望指点~
更多相关文章
- android高手之路--删除工程里面无用的代码和资源
- Android中去掉或更改标题栏TitleBar,theme的更改
- Android(安卓)源码通过makefile配置文件对系统APP进行代码混淆
- android 模拟器调用系统照相机
- 指尖上的Android之实战篇--说明篇(二)
- Android(安卓)切换系统语言源码分析
- Windows phone开发初体验之(四)-处理Windows Phone 中的方向更改
- Android(安卓)Binder 全解析(1) -- 概述
- 从Java/Android到Swift iOS开发:语言与框架对比