前几天,我们客户端这边收到了市场部的一个需求,需要在我们订单成交后,我们的客户端有一个上传交易凭证的功能,那么如何在Android实现上传图片的这个功能呢?在我进行编码之前,我先问自己几个问题。

第一, 图片是直接选择图库里的,还是需要拍照和选择图片两个选项?

因为在选择图片的时候,会有一个拍照的按钮,也可以实现拍照的功能。

第二, 需不需要本地缓存?

 本地缓存值得是,在我们的图片上传后,是否在下次直接显示,而不是从服务器读取。

第三,图片是否需要压缩?

众所周知,图片这种资源,因为体积较大,在网络上传输还是很慢的,所以,我们需要在我们的传输时,适当的对文件的大小进行压缩,那么就要根据我们自身的需求,按照一定的比例来进行压缩。

在思考完这几个问题后,根据我们自己的需求,我们在上传时有两个选项的,一个是拍照,一个是选择图片,另外我们需要做本地缓存,还有,图片上传不需要压缩。

那么我们就可以开始实现了,首先在我们的主fragment里,添加如下代码,如果你是activity,当然也可以。

做一个ImageView,作为我们上传的图像。

mPic1 = (ImageView) view.findViewById(R.id.ImageView01);
    mPic1.setOnClickListener(mPhotoListener);

    private View.OnClickListener mPhotoListener = new View.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			int id = v.getId();
			if (id == R.id.ImageView01) {
				Intent popupIntent = new Intent(getActivity(), PopupActivity.class);
				mPhotoId = id;
				startActivityForResult(popupIntent, 1);
			}
		}
	};

然后,我们跳转到另外一个PopupActivity,让我们选择,

PopupActivity.java

package com.chuanlaoda.android.activity;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.chuanloada.android.R;

public class PopupActivity extends Activity implements OnClickListener {
    private Button btn_take_photo, btn_pick_photo, btn_cancel;
    private LinearLayout layout;
    private Intent intent;

    private Button showList;
    private Button uploadNow;
    private String mCurrentPhotoPath;
    private Bitmap sourcePic;
    private File dir = null;

    private String picName = null;
    private String uploadFile = null;

    static Uri capturedImageUri=null;
    private Bitmap bitmap = null;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.popup);
        intent = getIntent();
        btn_take_photo = (Button) this.findViewById(R.id.btn_take_photo);
        btn_pick_photo = (Button) this.findViewById(R.id.btn_pick_photo);
        btn_cancel = (Button) this.findViewById(R.id.btn_cancel);

        layout = (LinearLayout) findViewById(R.id.pop_layout);

        layout.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), "提示:点击空白地方可以关闭",
                        Toast.LENGTH_SHORT).show();
            }
        });

        btn_cancel.setOnClickListener(this);
        btn_pick_photo.setOnClickListener(this);
        btn_take_photo.setOnClickListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        finish();
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        
        if (resultCode != RESULT_OK) {
            return;
        }
        if (data != null) {
            if (data.getExtras() != null)
            {
                bitmap = (Bitmap) data.getExtras().get("data");
                intent.putExtras(data.getExtras());
                intent.putExtra("uri", capturedImageUri);
                intent.putExtra("requestCode", requestCode);
                intent.putExtra("image", bitmap);
            }
            
            if (data.getData() != null)
                intent.setData(data.getData());            
        }
        setResult(requestCode, intent);
        finish();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btn_take_photo:
            dispatchTakePictureIntent();
            break;
        case R.id.btn_pick_photo:
            try {

                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(intent, 2);
            } catch (ActivityNotFoundException e) {

            }
            break;
        case R.id.btn_cancel:
            finish();
            break;
        default:
            break;
        }
    }
    
    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = "file:" + image.getAbsolutePath();
        return image;
    }
    
    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
            }
            // Continue only if the File was successfully created
            capturedImageUri = Uri.fromFile(photoFile);
            if (photoFile != null) {
                //takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
                startActivityForResult(takePictureIntent, 1);
            }
        }
    }
}

Popup.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical"
  >

<LinearLayout 
    android:id="@+id/pop_layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:layout_alignParentBottom="true"
     android:background="@drawable/btn_style_alert_dialog_background"
     >

    
    <Button
        android:id="@+id/btn_take_photo"
        android:layout_marginLeft="20dip"
        android:layout_marginRight="20dip"
        android:layout_marginTop="20dip"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="拍照"
        android:background="@drawable/btn_style_alert_dialog_button"
        android:textStyle="bold"
         />

    <Button
        android:id="@+id/btn_pick_photo"
        android:layout_marginLeft="20dip"
        android:layout_marginRight="20dip"
        android:layout_marginTop="5dip" 
         android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="从相册选择"
         android:background="@drawable/btn_style_alert_dialog_button"
         android:textStyle="bold"
         />

    <Button
        android:id="@+id/btn_cancel"
       android:layout_marginLeft="20dip"
       android:layout_marginRight="20dip"
       android:layout_marginTop="15dip" 
	   android:layout_marginBottom="15dip"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:text="取消"
       android:background="@drawable/btn_style_alert_dialog_cancel"
       android:textColor="#ffffff"
       android:textStyle="bold"
       
        />
</LinearLayout>
</RelativeLayout>

接下来就是我们需要在我们的主fragment (或者activity)中添加onActivityResult.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    	photo = (ImageView) mView.findViewById(mPhotoId);
    	String pfid=String.valueOf(BusinessDetailsFragment.getPosition(mPhotoId) + 1);
    	String gsid=String.valueOf(mBusinessId);
    	String cur_date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    	switch (resultCode) {
		case 1:
			if (data != null) {
				Uri mImageCaptureUri = (Uri) data.getExtras().get("uri");
				if (mImageCaptureUri != null) {
					Bitmap image;
					try {
						//image = MediaStore.Images.Media.getBitmap(this.getActivity().getContentResolver(), mImageCaptureUri);
						image = (Bitmap) data.getExtras().get("image");
						String fileFullPath = PhotoAPI.savePicsToSdcard(image, mFileLoc);
						PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
					    mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
					    Cache.addLastPhotoPath(pfid, fileFullPath);
					    Cache.addLastPhotoDate(gsid, cur_date);
					    PromptUtils.dismissProgressDialog();
					    
					    showDialog(mResult);
						if (image != null) {
							photo.setImageBitmap(image);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					Bundle extras = data.getExtras();
					if (extras != null) {
						Bitmap image = extras.getParcelable("data");
						String fileFullPath = PhotoAPI.savePicsToSdcard(image, mFileLoc);
						
						PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
					    mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
					    PromptUtils.dismissProgressDialog();
					    Cache.addLastPhotoPath(pfid, fileFullPath);
					    Cache.addLastPhotoDate(gsid, cur_date);
					    showDialog(mResult);
						if (image != null) {
							photo.setImageBitmap(image);
						}
					}
				}
			}
			break;
		case 2:
			if (data != null) {
				Uri mImageCaptureUri = data.getData();
				if (mImageCaptureUri != null) {
					Bitmap image;
					try {
						image = MediaStore.Images.Media.getBitmap(this.getActivity().getContentResolver(), mImageCaptureUri);					
						String fileFullPath = getRealPathFromURI(this.getActivity(),mImageCaptureUri);
						PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
					    mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
					    PromptUtils.dismissProgressDialog();
					    Cache.addLastPhotoPath(pfid, fileFullPath);
					    Cache.addLastPhotoDate(gsid, cur_date);
					    showDialog(mResult);
						if (image != null) {
							photo.setImageBitmap(image);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					Bundle extras = data.getExtras();
					if (extras != null) {
						String fileFullPath = getRealPathFromURI(this.getActivity(),mImageCaptureUri);
						PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
						mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
						PromptUtils.dismissProgressDialog();
						Cache.addLastPhotoPath(pfid, fileFullPath);
						Cache.addLastPhotoDate(gsid, cur_date);
						Bitmap image = extras.getParcelable("data");
						if (image != null) {
							photo.setImageBitmap(image);
						}
					}
				}
			}
			break;
		default:
			break;

		}
    }

另外,我们处理图片上传的代码在这里。

class UploadThread extends Thread {
	private String result = "";
	private String actionUrl;
	private String uploadFile;
	
	public UploadThread(String gsid, String pfid, String uploadFile) {
		String baseUrl = APIConfig.getAPIHost() + "uploadProof";
		this.actionUrl=baseUrl+"&gsid=" + gsid + "&pfid="+pfid; 
		this.uploadFile = uploadFile;
	}
	
	@Override
	public void run() {
		String end = "\r\n";
		String twoHyphens = "--";
		String boundary = "*****";
		try {

			URL url = new URL(actionUrl);
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			/* 允许Input、Output,不使用Cache */
			con.setDoInput(true);
			con.setDoOutput(true);
			con.setUseCaches(false);
			/* 设置传送的method=POST */
			con.setRequestMethod("POST");
			/* setRequestProperty */
			con.setRequestProperty("Connection", "Keep-Alive");
			con.setRequestProperty("Charset", "UTF-8");
			con.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=" + boundary);

			/* 设置DataOutputStream */
			DataOutputStream ds = new DataOutputStream(con.getOutputStream());
			ds.writeBytes(twoHyphens + boundary + end);
			ds.writeBytes("Content-Disposition: form-data; "
					+ "name=\"GooddShip\";filename=\"" + uploadFile + "\"" + end);
			ds.writeBytes(end);

			/* 取得文件的FileInputStream */
			FileInputStream fStream = new FileInputStream(uploadFile);

			/* 设置每次写入1024bytes */
			int bufferSize = 1024;
			byte[] buffer = new byte[bufferSize];

			int length = -1;
			/* 从文件读取数据至缓冲区 */
			while ((length = fStream.read(buffer)) != -1) {
				/* 将资料写入DataOutputStream中 */
				ds.write(buffer, 0, length);
			}

			ds.writeBytes(end);
			ds.writeBytes(twoHyphens + boundary + twoHyphens + end);

			/* close streams */
			fStream.close();
			ds.flush();

			/* 取得Response内容 */
			InputStream is = con.getInputStream();
			int ch;
			StringBuffer b = new StringBuffer();
			while ((ch = is.read()) != -1) {
				b.append((char) ch);
			}
			
			/* Parse JSON */
			JSONObject jObject = new JSONObject(b.toString());
			int code = jObject.getInt("Code");
			String error = jObject.getString("Error");
			String msg = jObject.getString("msg");
			
			if (code == 1) {
			/* 将Response显示于Dialog */
				result = "上传成功";
			} else result = "上传失败" + error;
			/* 关闭DataOutputStream */
			ds.close();
		} catch (Exception e) {
			result = "上传失败" + e;
		}
	}

然后就可以了,我们最终的效果如下。

Post android 图片上传 安卓上传照片_图片